home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 February
/
EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso
/
earcd
/
comm2
/
termsorc.lha
/
Extras
/
Source
/
term-source.lha
/
termMain.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-27
|
109KB
|
5,770 lines
/*
** termMain.c
**
** Program main routines and event loop
**
** Copyright © 1990-1995 by Olaf `Olsen' Barthel
** All Rights Reserved
*/
#include "termGlobal.h"
/* Argument vectors offsets. */
enum { ARG_WINDOW,ARG_PUBSCREEN,ARG_STARTUP,ARG_PORTNAME,ARG_SETTINGS,ARG_UNIT,ARG_DEVICE,
ARG_NEW,ARG_SYNC,ARG_QUIET,ARG_BEHIND,ARG_DEBUG,ARG_LANGUAGE,ARG_PHONEBOOK,ARG_AUTODIAL,
ARG_AUTOEXIT,
ARG_COUNT
};
/* Argument template. */
#define ARGTEMPLATE "WINDOW/K,PUBSCREEN/K,STARTUP/K,PORTNAME/K,SETTINGS/K,UNIT/K/N,DEVICE/K,NEW/S,SYNC/S,QUIET/S,BEHIND/S,DEBUG/S,LANGUAGE/K,PHONEBOOK/K,AUTODIAL/S,AUTOEXIT/S"
/* Local config path variable. */
STATIC STRPTR ConfigPath;
STATIC UBYTE __far ThePath[MAX_FILENAME_LENGTH];
/* Local dialing list. */
STATIC struct List *LocalDialList;
STATIC LONG LocalCount = -1;
/* Startup file name. */
STATIC UBYTE __far StartupFile[MAX_FILENAME_LENGTH];
/* Did we hang up the line? */
STATIC BOOLEAN HungUp = FALSE;
// Go on redialing?
STATIC BOOLEAN KeepRedialing = FALSE;
STATIC BOOLEAN AutoDial = FALSE;
STATIC BOOLEAN AutoExit = FALSE;
/* Poll OwnDevUnit.library for the device to become available again? */
STATIC BOOLEAN PollODU = FALSE;
STATIC UWORD PollODUCount = 0;
/* Cloned CLI data. */
STATIC struct CommandLineInterface *LocalCLI;
STATIC BPTR OldCLI;
/* Segment split routine, has to be local. */
STATIC struct Process * __regargs SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function);
STATIC VOID CloseLibs(VOID);
/* main():
*
* This is our main entry point, check for the right
* Kickstart version and fire off the background task
* if approritate.
*/
LONG
main()
{
STRPTR Result;
/* Are we running as a child of Workbench? */
ThisProcess = (struct Process *)SysBase -> ThisTask;
if(!ThisProcess -> pr_CLI)
{
WaitPort(&ThisProcess -> pr_MsgPort);
WBenchMsg = (struct WBStartup *)GetMsg(&ThisProcess -> pr_MsgPort);
}
else
WBenchMsg = NULL;
/* Now try to open dos.library and utility.library and go on examining
* our calling parameters.
*/
if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0)))
{
CloseLibs();
return(RETURN_FAIL);
}
if(!(UtilityBase = OpenLibrary("utility.library",0)))
{
CloseLibs();
return(RETURN_FAIL);
}
/* We were called from Shell. */
if(ThisProcess -> pr_CLI)
{
STRPTR *ArgArray;
/* Use the cute ReadArgs parser, allocate the
* argument vectors...
*/
if(ArgArray = (STRPTR *)AllocVec(sizeof(STRPTR) * (ARG_COUNT),MEMF_ANY|MEMF_CLEAR))
{
struct RDArgs *ArgsPtr;
if(ArgsPtr = (struct RDArgs *)AllocDosObject(DOS_RDARGS,TAG_DONE))
{
ArgsPtr -> RDA_ExtHelp = "\nUsage: term [WINDOW <Name>] [PUBSCREEN <Name>] [STARTUP <File name>]\n"
" [SETTINGS <File or path name>] [UNIT <Number>] [DEVICE <Name>]\n"
" [NEW] [SYNC] [QUIET] [BEHIND] [LANGUAGE <Name>] [PHONEBOOK <File name>]\n"
" [AUTODIAL] [AUTOEXIT]\n\n"
" Window = Output window specifier\n"
" PubScreen = Name of public screen to open window upon\n"
" Startup = ARexx script file to run on startup\n"
" Settings = Main configuration file name or path name to search for it\n"
" Unit = Serial device driver unit number\n"
" Device = Serial device driver name\n"
" New = Spawn a new `term' process\n"
" Sync = Keep links to Shell environment\n"
" Quiet = Start iconified\n"
" Behind = Open screen behind all other screens, don't activate the window\n"
" Phonebook = Name of phonebook file to load\n"
" Autodial = Dial phonebook entries which are marked for autodialing\n"
" Autoexit = Exit `term' after dialing all autodial entries\n"
" Language = Language to use for the user interface\n\n";
/* Parse the args (if any). */
if(ReadArgs(ARGTEMPLATE,(LONG *)ArgArray,ArgsPtr))
{
/* Pop a running `term' to the front? */
if((TermPort = (struct TermPort *)FindPort("term Port")) && !ArgArray[ARG_NEW])
{
if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
{
if(TermPort -> TopWindow)
BumpWindow(TermPort -> TopWindow);
}
TermPort = NULL;
FreeArgs(ArgsPtr);
FreeDosObject(DOS_RDARGS,ArgsPtr);
FreeVec(ArgArray);
CloseLibs();
return(RETURN_OK);
}
if(ArgArray[ARG_DEBUG])
DebugFlag = TRUE;
/* Special language requested? */
if(ArgArray[ARG_LANGUAGE])
strcpy(Language,ArgArray[ARG_LANGUAGE]);
/* Are we to use a special settings path? */
if(ArgArray[ARG_SETTINGS])
{
ConfigPath = ThePath;
strcpy(ThePath,ArgArray[ARG_SETTINGS]);
}
/* Are we to use a special ARexx host port name? */
if(ArgArray[ARG_PORTNAME])
strcpy(RexxPortName,ArgArray[ARG_PORTNAME]);
/* Are we to use a special output window name? */
if(ArgArray[ARG_WINDOW])
strcpy(WindowName,ArgArray[ARG_WINDOW]);
/* Are we to run an ARexx script on startup? */
if(ArgArray[ARG_STARTUP])
strcpy(StartupFile,ArgArray[ARG_STARTUP]);
// Load a special phonebook file
if(ArgArray[ARG_PHONEBOOK])
strcpy(LastPhone,ArgArray[ARG_PHONEBOOK]);
if(ArgArray[ARG_AUTODIAL])
AutoDial = TRUE;
if(ArgArray[ARG_AUTOEXIT])
AutoExit = TRUE;
/* Are we to open a window on a public screen? */
if(ArgArray[ARG_PUBSCREEN])
strcpy(SomePubScreenName,ArgArray[ARG_PUBSCREEN]);
/* Are we to use a special device? */
if(ArgArray[ARG_DEVICE])
{
strcpy(NewDevice,ArgArray[ARG_DEVICE]);
UseNewDevice = TRUE;
}
/* Are we to use a special unit number? */
if(ArgArray[ARG_UNIT])
{
NewUnit = *(LONG *)ArgArray[ARG_UNIT];
UseNewUnit = TRUE;
}
/* Are we to start up iconified? */
if(ArgArray[ARG_QUIET])
{
if(!StartupFile[0])
DoIconify = TRUE;
}
/* Hide the screen and don't activate the window? */
if(ArgArray[ARG_BEHIND])
KeepQuiet = TRUE;
/* We are to keep our links to
* the Shell.
*/
if(ArgArray[ARG_SYNC] || !ThisProcess -> pr_HomeDir)
{
BYTE OldPri = ThisProcess -> pr_Task . tc_Node . ln_Pri;
/* Open our resources and
* squeak on failure.
*/
if(Result = OpenAll(ConfigPath))
{
if(Result[0])
Printf("\33[1mterm:\33[0m %s!\a\n",Result);
FreeArgs(ArgsPtr);
FreeDosObject(DOS_RDARGS,ArgsPtr);
FreeVec(ArgArray);
CloseAll(TRUE);
return(RETURN_FAIL);
}
/* Go into main input
* loop.
*/
if(StackSize(NULL) < 16384)
{
LONG Success;
StackCall(&Success,16384,0,(LONG (* __stdargs)())HandleInput);
}
else
HandleInput();
/* Free the argument
* data.
*/
FreeArgs(ArgsPtr);
FreeDosObject(DOS_RDARGS,ArgsPtr);
FreeVec(ArgArray);
/* Restore old priority. */
SetTaskPri(ThisProcess,(LONG)OldPri);
/* Terminate execution. */
CloseAll(TRUE);
return(RETURN_OK);
}
FreeArgs(ArgsPtr);
}
else
{
PrintFault(IoErr(),"term");
FreeDosObject(DOS_RDARGS,ArgsPtr);
FreeVec(ArgArray);
CloseLibs();
return(RETURN_ERROR);
}
FreeDosObject(DOS_RDARGS,ArgsPtr);
}
FreeVec(ArgArray);
/* Create a new process from our code. */
if(!SegmentSplit("term main process",0,16384,HandleInput))
{
Printf("\33[1mterm:\33[0m Failed to create new process!\a\n");
CloseLibs();
return(RETURN_FAIL);
}
}
else
{
Printf("\33[1mterm:\33[0m Failed to allocate argument vectors!\a\n");
CloseLibs();
return(RETURN_FAIL);
}
}
else
{
/* Try to create a local CLI structure so
* Shell commands will receive a valid
* search path list.
*/
if(LocalCLI = CloneCLI(&WBenchMsg -> sm_Message))
{
OldCLI = ThisProcess -> pr_CLI;
ThisProcess -> pr_CLI = MKBADDR(LocalCLI);
}
WBenchLock = CurrentDir(WBenchMsg -> sm_ArgList -> wa_Lock);
/* Open icon.library, we want to take a
* look at the icon.
*/
if(IconBase = OpenLibrary("icon.library",0))
{
struct DiskObject *Icon;
/* Try to read the icon file. */
if(Icon = GetProgramIcon())
{
STRPTR Type;
if(FindToolType(Icon -> do_ToolTypes,"DEBUG"))
DebugFlag = TRUE;
/* Look for a `Language' tooltype. */
if(Type = FindToolType(Icon -> do_ToolTypes,"LANGUAGE"))
strcpy(Language,Type);
/* Look for a `Settings' tooltype. */
if(ConfigPath = FindToolType(Icon -> do_ToolTypes,"SETTINGS"))
{
/* Remember the path and continue. */
strcpy(ThePath,ConfigPath);
ConfigPath = ThePath;
}
// Look for a `Phonebook' tooltype.
if(Type = FindToolType(Icon -> do_ToolTypes,"PHONEBOOK"))
strcpy(LastPhone,Type);
if(FindToolType(Icon -> do_ToolTypes,"AUTODIAL"))
AutoDial = TRUE;
if(FindToolType(Icon -> do_ToolTypes,"AUTOEXIT"))
AutoExit = TRUE;
/* Look for a `Portname' tooltype. */
if(Type = FindToolType(Icon -> do_ToolTypes,"PORTNAME"))
strcpy(RexxPortName,Type);
else
RexxPortName[0] = 0;
/* Look for a `Window' tooltype. */
if(Type = FindToolType(Icon -> do_ToolTypes,"WINDOW"))
strcpy(WindowName,Type);
else
WindowName[0] = 0;
/* Look for a `Pubscreen' tooltype. */
if(Type = FindToolType(Icon -> do_ToolTypes,"PUBSCREEN"))
strcpy(SomePubScreenName,Type);
else
SomePubScreenName[0] = 0;
/* Look for a `Startup' tooltype. */
if(Type = FindToolType(Icon -> do_ToolTypes,"STARTUP"))
strcpy(StartupFile,Type);
else
StartupFile[0] = 0;
/* Look for a `Device' tooltype. */
if(Type = FindToolType(Icon -> do_ToolTypes,"DEVICE"))
{
if(Type[0])
{
strcpy(NewDevice,Type);
UseNewDevice = TRUE;
}
}
/* Look for a `Unit' tooltype. */
if(Type = FindToolType(Icon -> do_ToolTypes,"UNIT"))
{
if(Type[0])
{
NewUnit = Atol(Type);
UseNewUnit = TRUE;
}
}
/* Look for a `Quiet' tooltype. */
if(FindToolType(Icon -> do_ToolTypes,"QUIET"))
{
if(!StartupFile[0])
DoIconify = TRUE;
}
/* Look for a `Behind' tooltype. */
if(FindToolType(Icon -> do_ToolTypes,"BEHIND"))
KeepQuiet = TRUE;
/* Free the icon. */
FreeDiskObject(Icon);
}
CloseLibrary(IconBase);
IconBase = NULL;
}
/* Initialize this, so OpenAll will work with
* correct data.
*/
TermPort = (struct TermPort *)FindPort("term Port");
/* We were called from Workbench. */
if(Result = OpenAll(ConfigPath))
{
if(IntuitionBase && Result[0])
MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
CloseAll(TRUE);
}
else
{
if(StackSize(NULL) < 16384)
{
LONG Success;
StackCall(&Success,16384,0,(LONG (* __stdargs)())HandleInput);
}
else
HandleInput();
}
}
return(RETURN_OK);
}
/* CloseLibs():
*
* Plain and simple: close two libraries and clean up.
*/
STATIC VOID
CloseLibs(VOID)
{
if(UtilityBase)
{
CloseLibrary(UtilityBase);
UtilityBase = NULL;
}
if(WBenchMsg)
CurrentDir(WBenchLock);
if(DOSBase)
{
CloseLibrary(DOSBase);
DOSBase = NULL;
}
if(WBenchMsg)
{
Forbid();
ReplyMsg((struct Message *)WBenchMsg);
}
}
/* ProcessCleanup(register __d1 BPTR SegList):
*
* Frees all resource the main process has allocated when
* it exits.
*/
STATIC VOID __saveds __asm
ProcessCleanup(register __d1 BPTR SegList)
{
CloseAll(FALSE);
Forbid();
UnLoadSeg(SegList);
CloseLibrary(DOSBase);
DOSBase = NULL;
}
/* SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function):
*
* Create a new process from the current one.
*/
STATIC struct Process * __regargs
SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function)
{
struct Process *Child;
struct CommandLineInterface *CLI;
CLI = (struct CommandLineInterface *)BADDR(((struct Process *)SysBase -> ThisTask) -> pr_CLI);
Forbid();
Child = CreateNewProcTags(
NP_CommandName, "term",
NP_Name, Name,
NP_Priority, Pri,
NP_StackSize, StackSize,
NP_Entry, Function,
NP_Cli, TRUE,
NP_ExitCode, ProcessCleanup,
NP_ExitData, CLI -> cli_Module,
TAG_DONE);
if(Child)
CLI -> cli_Module = NULL;
Permit();
return(Child);
}
/* HandleInput():
*
* This is our main input loop (check window & serial).
*/
VOID __saveds
HandleInput()
{
BOOLEAN AlmostFinished = FALSE;
BYTE (* LocalSendLine)(register STRPTR,register LONG);
ThisProcess = (struct Process *)SysBase -> ThisTask;
/* Open the resources we need. */
if(!IntuitionBase)
{
STRPTR Result;
if(Result = OpenAll(ConfigPath))
{
if(IntuitionBase && Result[0])
MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
if(WBenchMsg)
CloseAll(TRUE);
return;
}
}
/* Tell the user what he probably doesn't know yet. */
if(TermVersion > Config -> SerialConfig -> LastVersionSaved || (TermVersion == Config -> SerialConfig -> LastVersionSaved && TermRevision > Config -> SerialConfig -> LastRevisionSaved))
{
BlockWindows();
ScreenToFront(Window -> WScreen);
DisplayBeep(Window -> WScreen);
DisplayBeep(Window -> WScreen);
ShowInfo(Window,LocaleString(MSG_ATTENTION_PLEASE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_REMINDER_TXT));
ReleaseWindows();
}
/* Give a hint. */
if(Config -> MiscConfig -> ProtectiveMode && !FirstInvocation)
{
BlockWindows();
if(Config -> SerialConfig -> BaudRate >= 4800 && Config -> SerialConfig -> HandshakingProtocol == HANDSHAKING_NONE && !Config -> SerialConfig -> DirectConnection)
{
ScreenToFront(Window -> WScreen);
if(MyEasyRequest(Window,LocaleString(MSG_NO_RTSCTS_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Config -> SerialConfig -> BaudRate))
{
SaveConfig(Config,PrivateConfig);
Config -> SerialConfig -> HandshakingProtocol = HANDSHAKING_RTSCTS_DSR;
ConfigSetup();
}
}
if(Config -> SerialConfig -> BaudRate >= 4800 && Config -> ModemConfig -> ConnectAutoBaud)
{
ScreenToFront(Window -> WScreen);
if(MyEasyRequest(Window,LocaleString(MSG_AUTOBAUD_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
{
SaveConfig(Config,PrivateConfig);
Config -> ModemConfig -> ConnectAutoBaud = FALSE;
ConfigSetup();
}
}
ReleaseWindows();
}
// Don't confuse the user yet, do it later ;-)
FirstInvocation = FALSE;
/* Start the online timer if a carrier is present? */
if(Config -> SerialConfig -> CheckCarrier && !Config -> SerialConfig -> DirectConnection)
{
/* Is the carrier signal present? */
if(!(GetSerialStatus() & CIAF_COMCD))
{
/* Go into online state. */
ObtainSemaphore(&OnlineSemaphore);
WasOnline = FALSE;
Online = TRUE;
ReleaseSemaphore(&OnlineSemaphore);
BaudCount = 0;
BaudBuffer[0] = 0;
BaudPending = FALSE;
CurrentPay = 0;
ObtainSemaphore(&PatternSemaphore);
ChosenEntry = NULL;
ChosenPattern = NULL;
ReleaseSemaphore(&PatternSemaphore);
Password[0] = 0;
UserName[0] = 0;
SendStartup = FALSE;
LimitCount = -1;
CurrentBBSName[0] = 0;
CurrentBBSComment[0] = 0;
CurrentBBSNumber[0] = 0;
SetDialMenu(FALSE);
}
}
/* Start up iconified? */
if(DoIconify)
{
HandleIconify();
DoIconify = FALSE;
if(MainTerminated)
goto Stop;
}
if(!KeepQuiet)
BumpWindow(Window);
/* Set up the public screen data. */
PubScreenStuff();
/* Change program priority. */
SetTaskPri(ThisProcess,(LONG)Config -> MiscConfig -> Priority);
BlockWindows();
/* Load the phone book. */
LoadPhonebook(LastPhone,NULL);
/* Build new menu strip. */
if(!AttachMenu(NULL))
{
if(IntuitionBase)
MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMINIT_FAILED_TO_CREATE_MENUS_TXT));
CloseAll(TRUE);
return;
}
else
{
if(Online)
SetDialMenu(FALSE);
}
/* Show our business card. */
if(!StartupFile[0] && !Config -> CommandConfig -> StartupMacro[0] && !KeepQuiet && !(PhonebookAutoDial || AutoDial))
{
if(ShowAbout(TRUE))
while(HandleRexx());
}
ReleaseWindows();
/* Don't do anything silly. */
KeepQuiet = FALSE;
LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_STARTED_TXT),TermName,TermDate);
/* Initialize the modem. */
LocalSendLine = SendLine;
SendLine = SendLineDial;
SerialCommand(Config -> ModemConfig -> ModemInit);
/* Execute the startup macro (if any). */
if(Config -> CommandConfig -> StartupMacro[0])
SerialCommand(Config -> CommandConfig -> StartupMacro);
if(SendLine == SendLineDial)
SendLine = LocalSendLine;
#ifdef BETA
{
STRPTR Warning =
"\f Just to make sure you know what you are using:\r\n"
"\r\n"
" \033#6This really is a\r\n"
" \033[5m\033#3BETA TEST\r\n"
" \033#4BETA TEST\033[0m\r\n"
" \033#6release!\r\n"
"\033#5\r\n"
" \033[4mDISCLAIMER:\033[0m\r\n"
"\r\n"
"This product is meant for educational purposes\r\n"
"only. If condition persists, consult your\r\n"
"physician. Edited for television. See label for\r\n"
"sequence. Avoid contact with skin. No purchase\r\n"
"necessary. Use only in well-ventilated area. Not\r\n"
"recommended for children. No anchovies unless\r\n"
"otherwise specified. Driver does not carry cash.\r\n"
"This supersedes all previous notices.\r\n";
ConProcess(Warning,strlen(Warning));
}
#endif // BETA
// Check if we should dial some entries from the phonebook
// right upon startup
if(PhonebookAutoDial || AutoDial)
{
LONG i,Count = 0;
for(i = 0 ; i < NumPhoneEntries ; i++)
{
if(Phonebook[i] -> Header -> AutoDial && Phonebook[i] -> Header -> Number[0])
{
Phonebook[i] -> Count = Count;
if(SortToList(NULL,Phonebook[i]))
Count++;
else
Phonebook[i] -> Count = -1;
}
}
if(Count > 0)
{
DoDial = DIAL_LIST;
if(PhonebookAutoExit || AutoExit)
KeepRedialing = TRUE;
}
}
/* Go into input loop... */
Loop: while(!MainTerminated)
{
if(Recording)
{
if(RecordingLine)
Status = STATUS_RECORDING_LINE;
else
Status = STATUS_RECORDING;
}
/* Handle the signal responses. */
if(DoDial != DIAL_LIST)
HandleResponse();
// Rebuild the main menu?
if(RebuildMenu)
{
struct Menu *Menu;
if(Menu = BuildMenu())
AttachMenu(Menu);
else
DisconnectDialMenu();
RebuildMenu = FALSE;
}
/* Are we to run an ARexx script file? */
if(StartupFile[0])
{
BlockWindows();
SendARexxCommand(StartupFile,TRUE);
ReleaseWindows();
StartupFile[0] = 0;
}
/* Are we to leave the main loop? */
if(MainTerminated)
break;
/* Make the user notice not too obvious events. */
if(FlowInfo . Changed)
HandleFlowChange();
/* Are we no longer online? */
ObtainSemaphore(&OnlineSemaphore);
if(!Online)
{
if(WasOnline)
{
ReleaseSemaphore(&OnlineSemaphore);
HandleOnlineCleanup(HungUp);
ObtainSemaphore(&OnlineSemaphore);
WasOnline = FALSE;
ReleaseSemaphore(&OnlineSemaphore);
HungUp = FALSE;
}
else
ReleaseSemaphore(&OnlineSemaphore);
}
else
ReleaseSemaphore(&OnlineSemaphore);
/* Now for public screen mode changes. */
if(FixPubScreenMode)
PubScreenStuff();
/* Now for window size changes. */
if(FixScreenSize)
ScreenSizeStuff();
/* Somebody told us to re-open the display
* (changed the terminal emulation/colour
* mode, etc.).
*/
if(ResetDisplay)
{
if(!DisplayReset())
break;
}
/* Let's see if we still have to display the
* online cost.
*/
ObtainSemaphore(&OnlineSemaphore);
if(CurrentPay && !Online)
{
ReleaseSemaphore(&OnlineSemaphore);
/* Reset the text rendering styles, font, etc. in
* order to keep the following text from getting
* illegible.
*/
SoftReset();
/* Display how much we expect
* the user will have to pay for
* this call.
*/
ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
CurrentPay = 0;
}
else
ReleaseSemaphore(&OnlineSemaphore);
/* Iconify the program? */
if(DoIconify)
{
HandleIconify();
if(MainTerminated)
break;
}
/* Reset the serial driver? */
if(ResetSerial)
{
HandleSerialReset();
if(MainTerminated)
break;
}
/* We are to release the serial.device (or
* whatever we are using) for some reason.
*/
if(ReleaseSerial)
{
HandleSerialRelease();
if(MainTerminated)
break;
}
/* Invoke the dialing function? */
if(DoDial != DIAL_IGNORE)
{
ObtainSemaphore(&OnlineSemaphore);
if(Online)
{
ReleaseSemaphore(&OnlineSemaphore);
FreeDialList(FALSE);
DoDial = DIAL_IGNORE;
Forbid();
if(DialMsg)
{
DialMsg -> rm_Result1 = RC_WARN;
DialMsg -> rm_Result2 = 0;
ReplyMsg(DialMsg);
DialMsg = NULL;
}
Permit();
}
else
{
ReleaseSemaphore(&OnlineSemaphore);
if(DoDial == DIAL_LIST)
{
BYTE OldStatus = Status;
DoDial = DIAL_IGNORE;
BlockWindows();
DialPanel();
FreeDialList(FALSE);
Status = OldStatus;
SetRedialMenu();
ReleaseWindows();
}
else
{
DoDial = DIAL_IGNORE;
HandleMenuCode(MEN_REDIAL,NULL);
}
}
}
/* Can we quit now? */
if(AlmostFinished && !CantQuit)
break;
}
/* Don't exit until all background processes
* have terminated.
*/
if(MainTerminated && CantQuit)
{
MainTerminated = FALSE;
AlmostFinished = TRUE;
goto Loop;
}
/* User wants to quit term, so let's try to close
* our magnificient screen and exit.
*/
Stop: if(Screen || SharedScreen)
{
struct Screen *WhichScreen;
/* There can be only one... */
if(Screen)
WhichScreen = Screen;
else
WhichScreen = SharedScreen;
// Can we quit now?
if(!(PubScreenStatus(WhichScreen,PSNF_PRIVATE) & PSNF_PRIVATE))
{
BlockWindows();
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
ReleaseWindows();
AlmostFinished = MainTerminated = FALSE;
goto Loop;
}
}
/* Send the modem exit command, shut down the
* serial.device and close all resources.
*/
LocalSendLine = SendLine;
SendLine = SendLineDial;
SerialCommand(Config -> ModemConfig -> ModemExit);
if(SendLine == SendLineDial)
SendLine = LocalSendLine;
ClearSerial();
LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_TERMINATED_TXT));
Say(LocaleString(MSG_TERMMAIN_BYE_BYE_TXT));
if(Phonebook && PhoneSize)
DeletePhonebook(Phonebook,PhoneSize,TRUE);
/* Clean up. */
if(LocalCLI)
{
ThisProcess -> pr_CLI = OldCLI;
DeleteCLI(LocalCLI);
}
if(!ThisProcess -> pr_CLI)
CloseAll(TRUE);
}
/* SendInputTextBuffer(STRPTR Buffer,LONG Len,BOOL Bell,BOOL ConvertLF):
*
* Transmit text the user typed or pasted via the
* clipboard.
*/
STATIC VOID __regargs
SendInputTextBuffer(STRPTR Buffer,LONG Len,BOOL Bell,BOOL ConvertLF)
{
UBYTE Mask,c;
if(Config -> SerialConfig -> StripBit8)
Mask = 0x7F;
else
Mask = 0xFF;
while(Len--)
{
switch(CharType[c = (*Buffer++) & Mask])
{
case CHAR_ENTER:
if(Status == STATUS_HOLDING)
{
if(Bell)
BellSignal();
}
else
{
if(ConvertLF)
{
switch(Config -> TerminalConfig -> SendCR)
{
case EOL_LF:
SerWrite("\n",1);
break;
case EOL_CR:
SerWrite("\r",1);
break;
case EOL_LFCR:
SerWrite("\n\r",2);
break;
case EOL_CRLF:
SerWrite("\r\n",2);
break;
}
}
else
{
switch(Config -> TerminalConfig -> SendLF)
{
case EOL_LF:
SerWrite("\n",1);
break;
case EOL_CR:
SerWrite("\r",1);
break;
case EOL_LFCR:
SerWrite("\n\r",2);
break;
case EOL_CRLF:
SerWrite("\r\n",2);
break;
}
}
}
break;
case CHAR_RETURN:
if(Status == STATUS_HOLDING)
{
if(Bell)
BellSignal();
}
else
{
switch(Config -> TerminalConfig -> SendCR)
{
case EOL_LF:
SerWrite("\n",1);
break;
case EOL_CR:
SerWrite("\r",1);
break;
case EOL_LFCR:
SerWrite("\n\r",2);
break;
case EOL_CRLF:
SerWrite("\r\n",2);
break;
}
}
break;
/* Stop in/output. */
case CHAR_XON:
if(Config -> SerialConfig -> xONxOFF)
Status = STATUS_HOLDING;
if(Config -> SerialConfig -> PassThrough)
SerWrite(&c,1);
break;
/* Restart in/output. */
case CHAR_XOFF:
if(Status == STATUS_HOLDING)
Status = STATUS_READY;
if(Config -> SerialConfig -> PassThrough)
SerWrite(&c,1);
break;
/* Any other character. */
case CHAR_VANILLA:
if(Status == STATUS_HOLDING)
{
if(Bell)
BellSignal();
}
else
{
if(Config -> TerminalConfig -> FontMode == FONT_IBM)
{
/* Convert special
* Amiga characters into
* alien IBM dialect.
*/
if(IBMConversion[c])
SerWrite(&IBMConversion[c],1);
else
SerWrite(&c,1);
}
else
SerWrite(&c,1);
}
break;
}
}
}
/* HandleWindow():
*
* This funny part checks the window(s) for incoming
* user input. Menus are handled elsewhere.
*/
BYTE
HandleWindow()
{
STATIC ULONG LastSeconds,LastMicros;
struct IntuiMessage *Message;
ULONG IClass,Code,Qualifier,Seconds,Micros;
LONG MouseX,MouseY,Len,GadgetID;
struct Gadget *Gadget;
UBYTE Char,InputBuffer[257];
struct Window *IDCMPWindow;
BOOLEAN Result = FALSE,ClickAndActivate = FALSE;
/* Are we reading input from the clipboard? */
if(ClipInput)
{
WORD Len = GetClip(InputBuffer,256,TRUE);
if(Len < 0)
{
CloseClip();
ClipInput = FALSE;
if(ClipXerox)
{
if(Config -> ClipConfig -> InsertSuffix[0])
SerialCommand(Config -> ClipConfig -> InsertSuffix);
ClipXerox = FALSE;
}
ClipPrefix = FALSE;
}
else
{
if(!ClipPrefix && ClipXerox)
{
if(Config -> ClipConfig -> InsertPrefix[0])
SerialCommand(Config -> ClipConfig -> InsertPrefix);
ClipPrefix = TRUE;
}
if(Len > 0)
SendInputTextBuffer(InputBuffer,Len,FALSE,Config -> ClipConfig -> ConvertLF);
Result = TRUE;
}
}
/* Any news in the mail? */
if(Message = (struct IntuiMessage *)GetMsg(Window -> UserPort))
{
/* A click into the window should activate it, but
* we don't want to have the character snapping activated
* under these conditions. In this case we rely upon
* Intuition sending the IDCMP_ACTIVEWINDOW and
* IDCMP_MOUSEBUTTONS event marked with the same
* creation time stamp. Even if the Intuition
* implementation should change no harm should
* be done.
*/
Seconds = Message -> Seconds;
Micros = Message -> Micros;
if(Seconds == LastSeconds && Micros == LastMicros && Message -> IDCMPWindow == Window)
{
if(Message -> Class == IDCMP_ACTIVEWINDOW || Message -> Class == IDCMP_MOUSEBUTTONS)
ClickAndActivate = TRUE;
}
LastSeconds = Seconds;
LastMicros = Micros;
/* Pick up the pieces. */
IClass = Message -> Class;
Code = Message -> Code;
Qualifier = Message -> Qualifier;
Gadget = (struct Gadget *)Message -> IAddress;
MouseX = Message -> MouseX;
MouseY = Message -> MouseY;
IDCMPWindow = Message -> IDCMPWindow;
if(IClass == IDCMP_IDCMPUPDATE)
GadgetID = GetTagData(GA_ID,0,(struct TagItem *)Gadget);
if(IClass == IDCMP_RAWKEY)
{
/* Perform key conversion. */
if(XEmulatorBase)
{
if(Len = XEmulatorUserMon(XEM_IO,InputBuffer,256,Message))
Char = InputBuffer[0];
}
else
Char = KeyConvert(Message,InputBuffer,&Len);
}
ReplyMsg(Message);
}
else
IClass = NULL;
/* Did we get any information? */
if(IClass)
{
/* The following messages probably
* originated from the fast! macro
* panel.
*/
if(IDCMPWindow == FastWindow)
{
switch(IClass)
{
/* Close the window. */
case IDCMP_CLOSEWINDOW:
CloseFastWindow();
return(TRUE);
/* Window size has changed for some reason. */
case IDCMP_NEWSIZE:
RefreshFastWindow(FALSE);
return(TRUE);
/* Some gadget was invoked. */
case IDCMP_GADGETUP:
case IDCMP_GADGETDOWN:
GadgetID = Gadget -> GadgetID;
case IDCMP_MOUSEMOVE:
case IDCMP_IDCMPUPDATE:
HandleFastWindowGadget(IClass,Code,GadgetID);
return(TRUE);
}
}
/* Status window activated? */
if(IDCMPWindow == StatusWindow)
{
if(IClass == IDCMP_ACTIVEWINDOW && !Config -> ScreenConfig -> SplitStatus)
NormalCursor();
if(IClass == IDCMP_CLOSEWINDOW)
{
Forbid();
ClrSignal(SIG_HANDSHAKE);
Signal(StatusProcess,SIG_CLOSEWINDOW);
Wait(SIG_HANDSHAKE);
Permit();
ClearMenuStrip(StatusWindow);
CloseWindowSafely(StatusWindow);
StatusWindow = NULL;
}
}
// What about the matrix window?
if(IDCMPWindow == MatrixWindow)
{
if(DispatchMatrixWindow(&IClass,Code,Qualifier,Char))
CloseMatrixWindow();
}
/* Main window message? */
if(IDCMPWindow == Window)
{
switch(IClass)
{
case IDCMP_INACTIVEWINDOW:
HoldClick = FALSE;
GhostCursor();
break;
case IDCMP_ACTIVEWINDOW:
// Take care of the chat gadget if necessary
ActivateChat(TRUE);
NormalCursor();
break;
case IDCMP_NEWSIZE:
/* Is a window clipping region installed? */
if(ClipRegion)
{
struct Rectangle RegionRectangle;
/* Install old region. */
InstallClipRegion(Window -> WLayer,OldRegion);
/* Fill in the clipping rectangle. */
RegionRectangle . MinX = Window -> BorderLeft;
RegionRectangle . MinY = Window -> BorderTop;
RegionRectangle . MaxX = Window -> Width - (Window -> BorderRight + 1);
RegionRectangle . MaxY = Window -> Height - (Window -> BorderBottom + 1);
/* Clear previous clipping region. */
ClearRegion(ClipRegion);
/* Set new clipping region. */
OrRectRegion(ClipRegion,&RegionRectangle);
/* Install new clipping region. */
OldRegion = InstallClipRegion(Window -> WLayer,ClipRegion);
}
ForceStatusUpdate();
HandleMenuCode(MEN_RESET_TERMINAL,Qualifier);
// Take care of the chat gadget if necessary
ActivateChat(TRUE);
TTYResize();
break;
case IDCMP_CLOSEWINDOW:
HandleMenuCode(MEN_QUIT,Qualifier);
break;
case IDCMP_MOUSEMOVE:
if(HoldClick)
{
if(!Marking)
SetMarker(ClickX,ClickY);
else
{
MouseX -= WindowLeft;
if(MouseX < 0)
MouseX = 0;
if(MouseX > WindowWidth - 1)
MouseX = WindowWidth - 1;
MouseY -= WindowTop;
if(MouseY < 0)
MouseY = 0;
if(MouseY > WindowHeight - 1)
MouseY = WindowHeight - 1;
MoveMarker(MouseX,MouseY);
}
}
break;
case IDCMP_MOUSEBUTTONS:
if(Code == SELECTUP)
ActivateChat(TRUE);
if((!ClickAndActivate || Code != SELECTDOWN) && (!XEmulatorBase || Config -> TerminalConfig -> EmulationMode != EMULATION_EXTERNAL))
{
if(Code == SELECTUP)
HoldClick = FALSE;
if(Code == SELECTDOWN)
{
MouseX -= WindowLeft;
if(MouseX < 0)
MouseX = 0;
if(MouseX > WindowWidth - 1)
MouseX = WindowWidth - 1;
MouseY -= WindowTop;
if(MouseY < 0)
MouseY = 0;
if(MouseY > WindowHeight - 1)
MouseY = WindowHeight - 1;
HoldClick = TRUE;
if(Qualifier & IEQUALIFIER_CONTROL)
{
WORD FirstX,FirstY;
FirstX = (MouseX * CharCellDenominator) / (TextFontWidth * CharCellNominator);
FirstY = MouseY / TextFontHeight;
if(FirstX < RasterWidth && FirstY < RasterHeight)
{
UBYTE Char;
ObtainSemaphore(RasterSemaphore);
Char = Raster[FirstY * RasterWidth + FirstX];
ReleaseSemaphore(RasterSemaphore);
if(Char)
{
SerWrite(&Char,1);
if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
switch(Config -> TerminalConfig -> SendCR)
{
case EOL_LF:
SerWrite("\n",1);
break;
case EOL_CR:
SerWrite("\r",1);
break;
case EOL_LFCR:
SerWrite("\n\r",2);
break;
case EOL_CRLF:
SerWrite("\r\n",2);
break;
}
}
}
}
return(TRUE);
}
if((Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT)) && (Qualifier & IEQUALIFIER_LEFTBUTTON))
{
WORD DeltaX,DeltaY;
ObtainSemaphore(&TerminalSemaphore);
DeltaX = (MouseX * CharCellDenominator) / (TextFontWidth * CharCellNominator) - CursorX;
DeltaY = MouseY / TextFontHeight - CursorY;
ReleaseSemaphore(&TerminalSemaphore);
if(DeltaX || DeltaY)
{
if(DeltaX > 0)
{
DeltaX++;
while(DeltaX--)
SerWrite("\33[C",3);
}
if(DeltaX < 0)
{
while(DeltaX++)
SerWrite("\33[D",3);
}
if(DeltaY > 0)
{
DeltaY++;
while(DeltaY--)
SerWrite("\33[B",3);
}
if(DeltaY < 0)
{
while(DeltaY++)
SerWrite("\33[A",3);
}
}
return(TRUE);
}
ReportMouse(TRUE,Window);
if(!FirstClick)
{
ULONG CurrentSecs,CurrentMicros;
CurrentTime(&CurrentSecs,&CurrentMicros);
FirstClick = TRUE;
if(ABS(ClickX - MouseX) <= TextFontWidth && ABS(ClickY - MouseY) <= TextFontHeight && DoubleClick(ClickSecs,ClickMicros,CurrentSecs,CurrentMicros))
{
DropMarker();
MarkWord(ClickX,ClickY);
return(TRUE);
}
else
{
CurrentTime(&ClickSecs,&ClickMicros);
FirstClick = FALSE;
ClickX = MouseX;
ClickY = MouseY;
}
}
else
{
CurrentTime(&ClickSecs,&ClickMicros);
FirstClick = FALSE;
ClickX = MouseX;
ClickY = MouseY;
}
if(Marking)
{
if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
MoveMarker(MouseX,MouseY);
else
{
DropMarker();
CurrentTime(&ClickSecs,&ClickMicros);
FirstClick = FALSE;
ClickX = MouseX;
ClickY = MouseY;
ReportMouse(TRUE,Window);
}
}
}
}
break;
}
}
/* Now for general information. */
switch(IClass)
{
case IDCMP_REFRESHWINDOW:
BeginRefresh(IDCMPWindow);
EndRefresh(IDCMPWindow,TRUE);
break;
case IDCMP_RAWKEY:
/* Take care of the numeric keypad. */
if((Qualifier & IEQUALIFIER_NUMERICPAD) && (Config -> EmulationConfig -> NumericMode == KEYMODE_APPLICATION))
{
STATIC STRPTR StringTable[22][2] =
{
"0", "\033Op",
"1", "\033Oq",
"2", "\033Or",
"3", "\033Os",
"4", "\033Ot",
"5", "\033Ou",
"6", "\033Ov",
"7", "\033Ow",
"8", "\033Ox",
"9", "\033Oy",
"-", "\033Om",
"+", "\033Ol", // This should really be a comma
".", "\033On",
"(", "\033OP",
"[", "\033OP",
"{", "\033OP",
"]", "\033OQ",
")", "\033OQ",
"}", "\033OQ",
"/", "\033OR",
"*", "\033OS",
"\r", "\033OM"
};
STATIC struct { UBYTE Code; STRPTR String; } CodeTable[18] =
{
0x0F, "\033Op", // "0"
0x1D, "\033Oq", // "1"
0x1E, "\033Or", // "2"
0x1F, "\033Os", // "3"
0x2D, "\033Ot", // "4"
0x2E, "\033Ou", // "5"
0x2F, "\033Ov", // "6"
0x3D, "\033Ow", // "7"
0x3E, "\033Ox", // "8"
0x3F, "\033Oy", // "9"
0x4A, "\033Om", // "-"
0x5E, "\033Ol", // "+", but this should really be a comma
0x3C, "\033On", // "."
0x5A, "\033OP", // "["
0x5B, "\033OQ", // "]"
0x5C, "\033OR", // "/"
0x5D, "\033OS", // "*"
0x43, "\033OM" // <cr>
};
STRPTR String = NULL;
WORD i;
for(i = 0 ; i < 22 ; i++)
{
if(Char == StringTable[i][0][0])
{
String = StringTable[i][1];
break;
}
}
if(!String)
{
for(i = 0 ; i < 18 ; i++)
{
if(Code == CodeTable[i] . Code)
{
String = CodeTable[i] . String;
break;
}
}
}
if(String)
{
if(ClipInput)
{
CloseClip();
ClipInput = ClipXerox = ClipPrefix = FALSE;
}
SerWrite(String,strlen(String));
Len = 0;
}
}
/* This looks like a raw, or better, now cooked key. */
if(Len)
{
switch(CharType[Char])
{
case CHAR_HELP:
GuideDisplay(CONTEXT_MAIN);
Len = 0;
break;
case CHAR_CURSOR:
if(ClipInput)
{
CloseClip();
ClipInput = ClipXerox = ClipPrefix = FALSE;
}
/* If in cursor key applications mode,
* send the corresponding string.
*/
if(Config -> EmulationConfig -> CursorMode == KEYMODE_APPLICATION)
{
STATIC STRPTR CursorTable[4] =
{
"\033OA",
"\033OB",
"\033OC",
"\033OD"
};
SerWrite(CursorTable[Char - CUP],3);
}
else
{
WORD QualType;
/* Find the appropriate qualifier. */
if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
QualType = 1;
else
{
if(Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
QualType = 2;
else
{
if(Qualifier & IEQUALIFIER_CONTROL)
QualType = 3;
else
QualType = 0;
}
}
/* Send the corresponding string. */
SerialCommand(CursorKeys -> Keys[QualType][Char - CUP]);
}
Len = 0;
break;
/* Any function key pressed? */
case CHAR_FUNCTION:
if(ClipInput)
{
CloseClip();
ClipInput = ClipXerox = ClipPrefix = FALSE;
}
if(Qualifier & IEQUALIFIER_CONTROL)
SerialCommand(MacroKeys -> Keys[3][Char - FN1]);
else
{
if(Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
SerialCommand(MacroKeys -> Keys[2][Char - FN1]);
else
{
if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
SerialCommand(MacroKeys -> Keys[1][Char - FN1]);
else
SerialCommand(MacroKeys -> Keys[0][Char - FN1]);
}
}
Len = 0;
break;
/* Anything else? */
default:
if(Len == 1 && Char == '\r' && Recording && !RecordingLine && (Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
{
RememberInputText("\r",1);
Len = 0;
RecordingLine = TRUE;
RememberResetInput();
RememberOutput = FALSE;
RememberInput = TRUE;
CheckItem(MEN_RECORD_LINE,TRUE);
}
break;
}
/* Any characters to send? */
if(Len)
SendInputTextBuffer(InputBuffer,Len,TRUE,FALSE);
}
break;
/* A menu item was selected. */
case IDCMP_MENUPICK:
HandleMenu(Code,Qualifier);
// Take care of the chat gadget if necessary
ActivateChat(TRUE);
break;
/* Menu help is required. */
case IDCMP_MENUHELP:
if(MENUNUM(Code) == NOMENU || MENUNUM(Code) > 9 || ITEMNUM(Code) == NOITEM)
GuideDisplay(CONTEXT_MAIN_MENU);
else
GuideDisplay(CONTEXT_PROJECT_MEN + MENUNUM(Code));
break;
}
return(TRUE);
}
return(Result);
}
/* HandleLocalDialList(BYTE ClearIt):
*
* Invoke the local dialing list or clear it.
*/
STATIC VOID __regargs
HandleLocalDialList(BYTE ClearIt)
{
if(Menu)
{
struct Menu *ThisMenu;
struct MenuItem *Item;
if(Window)
ClearMenuStrip(Window);
if(StatusWindow)
ClearMenuStrip(StatusWindow);
if(FastWindow)
ClearMenuStrip(FastWindow);
for(ThisMenu = Menu ; ThisMenu ; ThisMenu = ThisMenu -> NextMenu)
{
if(Item = ThisMenu -> FirstItem)
{
do
{
if((ULONG)GTMENUITEM_USERDATA(Item) >= DIAL_MENU_LIMIT)
Item -> Flags &= ~CHECKED;
if(Item -> SubItem)
{
struct MenuItem *SubItem = Item -> SubItem;
do
{
if((ULONG)GTMENUITEM_USERDATA(SubItem) >= DIAL_MENU_LIMIT)
SubItem -> Flags &= ~CHECKED;
}
while(SubItem = SubItem -> NextItem);
}
}
while(Item = Item -> NextItem);
}
}
if(Window)
ResetMenuStrip(Window,Menu);
if(StatusWindow)
ResetMenuStrip(StatusWindow,Menu);
if(FastWindow)
ResetMenuStrip(FastWindow,Menu);
}
if(LocalDialList)
{
ObtainSemaphore(&OnlineSemaphore);
if(LocalDialList -> lh_Head -> ln_Succ && !Online && !ClearIt)
{
ReleaseSemaphore(&OnlineSemaphore);
FreeDialList(TRUE);
DialList = LocalDialList;
LocalDialList = NULL;
LocalCount = -1;
SetRedialMenu();
HandleMenuCode(MEN_REDIAL,NULL);
}
else
{
ReleaseSemaphore(&OnlineSemaphore);
FreeList(LocalDialList);
FreeVecPooled(LocalDialList);
LocalDialList = NULL;
LocalCount = -1;
}
}
}
/* HandleMenuCode(ULONG Code,ULONG Qualifier):
*
* Handle each function associated with a menu code.
*/
VOID __regargs
HandleMenuCode(ULONG Code,ULONG Qualifier)
{
struct FileRequester *FileRequest;
UBYTE DummyBuffer[MAX_FILENAME_LENGTH],
*DummyChar;
BYTE OldStatus = Status;
BPTR SomeFile;
APTR OldPtr;
struct MenuItem *Item;
switch(Code)
{
/* Save screen as IFF-ILBM file. */
case MEN_SAVE_AS_PICTURE:
BlockWindows();
if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_SCREEN_IFF_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),TRUE))
{
if(!SaveWindow(DummyBuffer,Window))
ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
FreeAslRequest(FileRequest);
}
ReleaseWindows();
break;
/* Save screen as ASCII file. */
case MEN_SAVE_AS_TEXT:
BlockWindows();
if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_SCREEN_ASCII_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
{
LONG Error = 0;
if(GetFileSize(DummyBuffer))
{
switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
{
case 1: SomeFile = Open(DummyBuffer,MODE_NEWFILE);
break;
case 2: if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
{
if(Seek(SomeFile,0,OFFSET_END) == -1)
{
Close(SomeFile);
SomeFile = NULL;
}
}
break;
case 0: SomeFile = ~0;
break;
}
}
else
SomeFile = Open(DummyBuffer,MODE_NEWFILE);
if(SomeFile)
{
if(SomeFile != ~0)
{
LONG i,j;
UBYTE *Buffer;
for(i = 0 ; i < RasterHeight ; i++)
{
Buffer = &Raster[i * RasterWidth];
j = RasterWidth - 1;
while(j >= 0 && Buffer[j] == ' ')
j--;
if(j >= 0)
{
SetIoErr(0);
if(FWrite(SomeFile,Buffer,j + 1,1) < 1)
{
Error = IoErr();
break;
}
}
SetIoErr(0);
if(FWrite(SomeFile,"\n",1,1) < 1)
{
Error = IoErr();
break;
}
}
Close(SomeFile);
AddProtection(DummyBuffer,FIBF_EXECUTE);
if(Config -> MiscConfig -> CreateIcons)
AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
}
}
else
Error = IoErr();
if(Error)
ShowError(Window,ERR_SAVE_ERROR,Error,DummyBuffer);
FreeAslRequest(FileRequest);
}
ReleaseWindows();
break;
/* Print the screen (pure ASCII). */
case MEN_PRINT_SCREEN:
BlockWindows();
if(RasterEnabled)
PrintSomething(PRINT_SCREEN);
else
MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_NO_DATA_TO_PRINT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
ReleaseWindows();
break;
/* Print the screen (graphics). */
case MEN_PRINT_SCREEN_AS_GFX:
BlockWindows();
PrintScreenGfx();
ReleaseWindows();
break;
/* Print the clipboard contents. */
case MEN_PRINT_CLIP:
BlockWindows();
PrintSomething(PRINT_CLIP);
ReleaseWindows();
break;
/* Open/close the terminal capture file. */
case MEN_CAPTURE_TO_FILE:
if(FileCapture)
CloseFileCapture();
else
OpenFileCapture(FALSE);
break;
/* Open/close the terminal capture file. */
case MEN_CAPTURE_TO_RAW_FILE:
if(FileCapture)
CloseFileCapture();
else
OpenFileCapture(TRUE);
break;
/* Start/terminate the printer
* capture.
*/
case MEN_CAPTURE_TO_PRINTER:
if(PrinterCapture)
ClosePrinterCapture(TRUE);
else
OpenPrinterCapture(FALSE);
break;
/* Iconify the program. */
case MEN_ICONIFY:
if(Config -> MiscConfig -> ProtectiveMode)
{
ObtainSemaphore(&OnlineSemaphore);
if(Online && Config -> MiscConfig -> ReleaseDevice && !(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
{
ReleaseSemaphore(&OnlineSemaphore);
BlockWindows();
if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
{
ReleaseWindows();
break;
}
ReleaseWindows();
}
else
ReleaseSemaphore(&OnlineSemaphore);
}
DoIconify = TRUE;
break;
/* Say who we are. */
case MEN_ABOUT:
BlockWindows();
#ifdef DATAFEED
if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
STATIC UBYTE LastFile[40],LastPath[256];
extern BPTR DataFeed;
if(DataFeed)
{
Close(DataFeed);
DataFeed = NULL;
}
if(FileRequest = GetFile(Window,"Select terminal test file",LastPath,LastFile,DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SELECT_TXT),FALSE))
{
if(GetFileSize(DummyBuffer))
{
if(DataFeed = Open(DummyBuffer,MODE_OLDFILE))
{
strcpy(LastFile,FileRequest -> fr_File);
strcpy(LastPath,FileRequest -> fr_Drawer);
if(Kick30)
SetVBuf(DataFeed,NULL,2,8192);
}
}
FreeAslRequest(FileRequest);
}
}
else
#endif /* DATAFEED */
ShowAbout(FALSE);
ReleaseWindows();
break;
/* Terminate the program. */
case MEN_QUIT:
if((Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) || !Config -> MiscConfig -> ProtectiveMode)
MainTerminated = TRUE;
else
{
STRPTR Buffer;
LONG OldLen,Len = strlen(LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT)) + 3;
OldLen = Len;
ObtainSemaphore(&OnlineSemaphore);
if(Online)
Len += strlen(LocaleString(MSG_WAIT_PROGRAM_IS_STILL_ONLINE_TXT)) + 4;
ReleaseSemaphore(&OnlineSemaphore);
if(BufferChanged)
Len += strlen(LocaleString(MSG_WAIT_REVIEW_BUFFER_NOT_SAVED_TXT)) + 4;
if(ConfigChanged)
Len += strlen(LocaleString(MSG_WAIT_CONFIGURATION_HAS_BEEN_CHANGED_TXT)) + 4;
if(PhonebookChanged)
Len += strlen(LocaleString(MSG_WAIT_PHONEBOOK_NOT_SAVED_TXT)) + 4;
if(TranslationChanged)
Len += strlen(LocaleString(MSG_WAIT_TRANSLATION_TABLES_CHANGED_TXT)) + 4;
if(MacroChanged)
Len += strlen(LocaleString(MSG_WAIT_MACRO_KEYS_CHANGED_TXT)) + 4;
if(CursorKeysChanged)
Len += strlen(LocaleString(MSG_WAIT_CURSOR_KEYS_CHANGED_TXT)) + 4;
if(FastMacrosChanged)
Len += strlen(LocaleString(MSG_WAIT_FAST_MACROS_CHANGED_TXT)) + 4;
if(HotkeysChanged)
Len += strlen(LocaleString(MSG_WAIT_HOTKEYS_CHANGED_TXT)) + 4;
if(SpeechChanged)
Len += strlen(LocaleString(MSG_WAIT_SPEECH_SETTINGS_CHANGED_TXT)) + 4;
if(SoundChanged)
Len += strlen(LocaleString(MSG_WAIT_SOUND_SETTINGS_CHANGED_TXT)) + 4;
BlockWindows();
OldPtr = ThisProcess -> pr_WindowPtr;
ThisProcess -> pr_WindowPtr = (APTR)Window;
if(OldLen != Len)
{
if(Buffer = (STRPTR)AllocVecPooled(Len,MEMF_ANY))
{
SPrintf(Buffer,"%s\n\n",LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT));
ObtainSemaphore(&OnlineSemaphore);
if(Online)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_PROGRAM_IS_STILL_ONLINE_TXT));
strcat(Buffer,SharedBuffer);
}
ReleaseSemaphore(&OnlineSemaphore);
if(BufferChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_REVIEW_BUFFER_NOT_SAVED_TXT));
strcat(Buffer,SharedBuffer);
}
if(ConfigChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_CONFIGURATION_HAS_BEEN_CHANGED_TXT));
strcat(Buffer,SharedBuffer);
}
if(PhonebookChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_PHONEBOOK_NOT_SAVED_TXT));
strcat(Buffer,SharedBuffer);
}
if(TranslationChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_TRANSLATION_TABLES_CHANGED_TXT));
strcat(Buffer,SharedBuffer);
}
if(MacroChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_MACRO_KEYS_CHANGED_TXT));
strcat(Buffer,SharedBuffer);
}
if(CursorKeysChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_CURSOR_KEYS_CHANGED_TXT));
strcat(Buffer,SharedBuffer);
}
if(FastMacrosChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_FAST_MACROS_CHANGED_TXT));
strcat(Buffer,SharedBuffer);
}
if(HotkeysChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_HOTKEYS_CHANGED_TXT));
strcat(Buffer,SharedBuffer);
}
if(SpeechChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_SPEECH_SETTINGS_CHANGED_TXT));
strcat(Buffer,SharedBuffer);
}
if(MyEasyRequest(Window,Buffer,LocaleString(MSG_GLOBAL_YES_NO_TXT)))
MainTerminated = TRUE;
FreeVecPooled(Buffer);
}
else
MainTerminated = TRUE;
}
else
MainTerminated = TRUE;
ThisProcess -> pr_WindowPtr = OldPtr;
ReleaseWindows();
}
break;
/* Feed the contents of the clipboard
* into the input stream.
*/
case MEN_PASTE:
if(!OpenClip(Config -> ClipConfig -> ClipboardUnit))
{
ClipInput = TRUE;
if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
ClipXerox = TRUE;
}
else
ClipInput = FALSE;
break;
case MEN_COPY:
if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
ClipMarker(TRUE);
else
ClipMarker(FALSE);
break;
case MEN_CLEAR:
DropMarker();
break;
/* Execute an AmigaDOS command. */
case MEN_EXECUTE_DOS_COMMAND:
BlockWindows();
/* Enter the name of the command. */
if(GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_AMIGADOS_COMMAND_TXT),AmigaDOSCommandBuffer))
SendAmigaDOSCommand(AmigaDOSCommandBuffer);
ReleaseWindows();
break;
/* Execute an ARexx script command. */
case MEN_EXECUTE_REXX_COMMAND:
BlockWindows();
/* Get the rexx file name/program. */
if(GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_AREXX_COMMAND_TXT),ARexxCommandBuffer))
SendARexxCommand(ARexxCommandBuffer,TRUE);
ReleaseWindows();
break;
/* Turn recording on/off. */
case MEN_RECORD:
if(GetItem(MEN_RECORD))
{
if(!Recording)
{
if(CreateRecord(CurrentBBSName[0] ? CurrentBBSName : LocaleString(MSG_SCREENPANEL_UNKNOWN_TXT)))
{
RememberResetOutput();
RememberResetInput();
RememberOutput = TRUE;
Recording = TRUE;
RecordingLine = FALSE;
OnItem(MEN_RECORD_LINE);
}
}
}
else
{
if(Recording)
{
FinishRecord();
RememberOutput = FALSE;
RememberInput = FALSE;
Recording = FALSE;
RecordingLine = FALSE;
OffItem(MEN_RECORD_LINE);
Status = STATUS_READY;
}
}
break;
case MEN_RECORD_LINE:
if(Recording)
{
if(GetItem(MEN_RECORD))
{
if(!RecordingLine)
{
RecordingLine = TRUE;
RememberResetInput();
RememberOutput = FALSE;
RememberInput = TRUE;
}
}
else
{
if(RecordingLine)
{
RememberSpill();
RecordingLine = FALSE;
RememberOutput = TRUE;
RememberInput = FALSE;
}
}
}
break;
case MEN_DISABLE_TRAPS:
if(Item = FindThisItem(Menu,MEN_DISABLE_TRAPS))
{
ObtainSemaphore(&GenericListTable[GLIST_TRAP] -> ListSemaphore);
if(!(Item -> Flags & CHECKED) && GenericListTable[GLIST_TRAP] -> ListHeader . mlh_Head -> mln_Succ)
WatchTraps = TRUE;
else
WatchTraps = FALSE;
ReleaseSemaphore(&GenericListTable[GLIST_TRAP] -> ListSemaphore);
}
break;
/* Edit the trap settings? */
case MEN_EDIT_TRAPS:
BlockWindows();
TrapPanel();
if(Item = FindThisItem(Menu,MEN_DISABLE_TRAPS))
{
if(WatchTraps)
Item -> Flags &= ~CHECKED;
else
Item -> Flags |= CHECKED;
}
ReleaseWindows();
break;
/* Set the name we will use to open the
* default console output window for
* AmigaDOS commands and ARexx scripts.
*/
case MEN_SET_CONSOLE:
BlockWindows();
if(GetString(FALSE,FALSE,0,LocaleString(MSG_TERMMAIN_SET_CONSOLE_WINDOW_TXT),WindowName))
SetEnvDOS("TERMWINDOW",WindowName);
ReleaseWindows();
break;
/* Open the phonebook and dial the
* list of entries the user will select.
*/
case MEN_PHONEBOOK:
BlockWindows();
HandleLocalDialList(TRUE);
while(PhonePanel(Qualifier))
{
if(!DialPanel())
{
Status = OldStatus;
break;
}
Status = OldStatus;
}
if(!PhonebookAutoExit)
KeepRedialing = FALSE;
SetRedialMenu();
ReleaseWindows();
break;
/* Redial those dial list entries which
* we were unable to connect.
*/
case MEN_REDIAL:
BlockWindows();
/* If the modem is still online, provide help. */
if(!AskDial(Window))
{
ReleaseWindows();
break;
}
HandleLocalDialList(TRUE);
do
{
if(!DialPanel())
{
KeepRedialing = FALSE;
Status = OldStatus;
break;
}
Status = OldStatus;
}
while(PhonePanel(NULL));
if(!PhonebookAutoExit)
KeepRedialing = FALSE;
SetRedialMenu();
ReleaseWindows();
break;
/* Dial a single number. */
case MEN_DIAL_NUMBER:
BlockWindows();
/* If the modem is still online, provide help. */
if(!AskDial(Window))
{
ReleaseWindows();
break;
}
HandleLocalDialList(TRUE);
if(GetString(FALSE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_PHONE_NUMBER_TXT),DialNumberBuffer))
{
if(DialNumberBuffer[0])
{
struct List *LocalList;
if(LocalList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY|MEMF_CLEAR))
{
struct PhoneNode *DialNode;
LONG Len = strlen(DialNumberBuffer);
NewList(LocalList);
if(DialNode = (struct PhoneNode *)AllocVecPooled(sizeof(struct PhoneNode) + Len + 1,MEMF_ANY|MEMF_CLEAR))
{
DialNode -> VanillaNode . ln_Name = (char *)(DialNode + 1);
strcpy(DialNode -> VanillaNode . ln_Name,DialNumberBuffer);
AddTail(LocalList,&DialNode -> VanillaNode);
FreeDialList(TRUE);
DialList = LocalList;
DialPanel();
Status = OldStatus;
}
else
FreeVecPooled(LocalList);
}
}
}
SetRedialMenu();
ReleaseWindows();
break;
/* Send a break across the serial line. */
case MEN_SEND_BREAK:
SendBreak();
break;
/* Hang up the phone line. */
case MEN_HANG_UP:
FullHangup(FALSE);
break;
/* Wait a bit... */
case MEN_WAIT:
{
struct Window *ReqWindow;
struct EasyStruct Easy;
Easy . es_StructSize = sizeof(struct EasyStruct);
Easy . es_Flags = NULL;
Easy . es_Title = (UBYTE *)LocaleString(MSG_TERMAUX_TERM_REQUEST_TXT);
Easy . es_GadgetFormat = (UBYTE *)LocaleString(MSG_GLOBAL_CONTINUE_TXT);
Easy . es_TextFormat = (UBYTE *)LocaleString(MSG_TERMMAIN_WAITING_TXT);
BlockWindows();
if(ReqWindow = BuildEasyRequest(Window,&Easy,IDCMP_RAWKEY,NULL))
{
ULONG Signals;
BYTE Done = FALSE;
/* Don't echo serial output. */
Quiet = TRUE;
do
{
SerWrite(" \b",2);
HandleSerial();
StartTime(1,0);
Signals = Wait(SIG_TIMER | PORTMASK(ReqWindow -> UserPort));
if(Signals & SIG_TIMER)
WaitIO(TimeRequest);
if(Signals & PORTMASK(ReqWindow -> UserPort))
{
LONG Result;
ULONG IDCMP = NULL;
Result = SysReqHandler(ReqWindow,&IDCMP,FALSE);
if(Result == 0 || (Result == -2 && !(IDCMP & IDCMP_RAWKEY)))
{
if(!CheckIO(TimeRequest))
AbortIO(TimeRequest);
WaitIO(TimeRequest);
Done = TRUE;
}
}
}
while(!Done);
Quiet = FALSE;
FreeSysRequest(ReqWindow);
}
ReleaseWindows();
}
break;
/* Flush the serial buffers. */
case MEN_FLUSH_BUFFER:
ClearSerial();
RestartSerial();
break;
/* Release the serial device for other
* applications.
*/
case MEN_RELEASE_DEVICE:
ReleaseSerial = TRUE;
break;
case MEN_UPLOAD_ASCII:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary,Config -> TransferConfig -> ASCIIUploadType))
{
BinaryTransfer = FALSE;
StartXprSend(TRANSFER_ASCII,TRUE);
BinaryTransfer = TRUE;
}
ResetProtocol();
ReleaseWindows();
break;
case MEN_DOWNLOAD_ASCII:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> ASCIIDownloadLibrary,Config -> TransferConfig -> ASCIIDownloadType))
{
BinaryTransfer = FALSE;
StartXprReceive(TRANSFER_ASCII,NULL,TRUE);
BinaryTransfer = TRUE;
}
ResetProtocol();
ReleaseWindows();
break;
case MEN_UPLOAD_TEXT:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary,Config -> TransferConfig -> TextUploadType))
{
BinaryTransfer = FALSE;
StartXprSend(TRANSFER_TEXT,TRUE);
BinaryTransfer = TRUE;
}
ResetProtocol();
ReleaseWindows();
break;
case MEN_DOWNLOAD_TEXT:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> TextDownloadLibrary,Config -> TransferConfig -> TextDownloadType))
{
BinaryTransfer = FALSE;
StartXprReceive(TRANSFER_TEXT,NULL,TRUE);
BinaryTransfer = TRUE;
}
ResetProtocol();
ReleaseWindows();
break;
/* Edit and transfer a file. */
case MEN_EDIT_AND_UPLOAD_TEXT:
BlockWindows();
if(!Config -> PathConfig -> Editor[0])
GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_NAME_OF_EDITOR_TO_USE_TXT),Config -> PathConfig -> Editor);
if(Config -> PathConfig -> Editor[0])
{
if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_EDIT_AND_TRANSFER_FILE_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_TERMMAIN_EDIT_TXT),TRUE))
{
UBYTE CompoundName[512];
strcpy(CompoundName,Config -> PathConfig -> Editor);
strcat(CompoundName," \"");
strcat(CompoundName,DummyBuffer);
strcat(CompoundName,"\"");
LaunchCommand(CompoundName);
BumpWindow(Window);
FreeAslRequest(FileRequest);
if(GetFileSize(DummyBuffer))
{
BinaryTransfer = FALSE;
switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILE_AS_TXT),LocaleString(MSG_TERMMAIN_ASCII_UPLOAD_CANCEL_TXT),FilePart(DummyBuffer)))
{
case 1: if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary,Config -> TransferConfig -> ASCIIUploadType))
SendTextFile(TRANSFER_ASCII,DummyBuffer);
ResetProtocol();
break;
case 2: if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary,Config -> TransferConfig -> TextUploadType))
SendTextFile(TRANSFER_TEXT,DummyBuffer);
ResetProtocol();
break;
}
BinaryTransfer = TRUE;
}
}
}
ReleaseWindows();
break;
case MEN_UPLOAD_BINARY:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> BinaryUploadLibrary,Config -> TransferConfig -> BinaryUploadType))
{
BinaryTransfer = TRUE;
StartXprSend(TRANSFER_BINARY,TRUE);
}
ResetProtocol();
ReleaseWindows();
break;
/* Download some files. */
case MEN_DOWNLOAD_BINARY:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> BinaryDownloadLibrary,Config -> TransferConfig -> BinaryDownloadType))
{
BinaryTransfer = TRUE;
StartXprReceive(TRANSFER_BINARY,NULL,TRUE);
}
ResetProtocol();
ReleaseWindows();
break;
/* Clear the contents of the scrollback
* buffer.
*/
case MEN_CLEAR_BUFFER:
if(Lines)
{
BlockWindows();
if((Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) || !Config -> MiscConfig -> ProtectiveMode)
{
FreeBuffer();
TerminateBuffer();
}
else
{
if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Lines))
{
FreeBuffer();
TerminateBuffer();
}
}
ReleaseWindows();
}
break;
/* Display the scrollback buffer.
* Notify the scrollback task or
* fire it off if appropriate.
*/
case MEN_DISPLAY_BUFFER:
if(!LaunchBuffer())
{
BlockWindows();
MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNABLE_TO_CREATE_BUFFER_TASK_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
ReleaseWindows();
}
break;
/* Close the buffer display. */
case MEN_CLOSE_BUFFER:
TerminateBuffer();
break;
/* Is the buffer to be frozen? */
case MEN_FREEZE_BUFFER:
if(Item = FindThisItem(Menu,MEN_FREEZE_BUFFER))
{
if(Item -> Flags & CHECKED)
BufferFrozen = TRUE;
else
BufferFrozen = FALSE;
ConOutputUpdate();
}
break;
/* Load the buffer contents from a file. */
case MEN_OPEN_BUFFER:
BlockWindows();
if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_LOAD_BUFFER_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_LOAD_TXT),FALSE))
{
if(GetFileSize(DummyBuffer))
{
if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
{
if(Lines)
{
switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_TERMMAIN_DISCARD_APPPEND_CANCEL_TXT),Lines))
{
case 1: FreeBuffer();
break;
case 2: break;
case 0: Close(SomeFile);
SomeFile = NULL;
break;
}
}
if(SomeFile)
{
LONG Len;
LineRead(NULL,NULL,NULL);
while((Len = LineRead(SomeFile,DummyBuffer,80)) > 0)
CaptureParser(DummyBuffer,Len,AddLine);
Close(SomeFile);
BufferChanged = TRUE;
}
}
else
ShowError(Window,ERR_LOAD_ERROR,IoErr(),DummyBuffer);
}
FreeAslRequest(FileRequest);
}
ReleaseWindows();
break;
/* Save the contents of the scrollback
* buffer to a file (line by line).
*/
case MEN_SAVE_BUFFER_AS:
BlockWindows();
if(!Lines || !BufferLines)
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
else
{
if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_BUFFER_TXT),Config -> CaptureConfig -> BufferPath,"",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
{
LONG Error = 0;
SomeFile = NULL;
/* If the file we are about
* to create already exists,
* ask the user whether we are
* to create, append or skip
* the file.
*/
if(GetFileSize(DummyBuffer))
{
switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
{
case 1: SomeFile = Open(DummyBuffer,MODE_NEWFILE);
break;
case 2: if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
{
if(Seek(SomeFile,0,OFFSET_END) == -1)
{
Close(SomeFile);
SomeFile = NULL;
}
}
break;
}
}
else
SomeFile = Open(DummyBuffer,MODE_NEWFILE);
if(SomeFile)
{
LONG i,Len;
/* Obtain the semaphore required
* to gain access to the line buffer
*/
ObtainSemaphore(BufferSemaphore);
for(i = 0 ; i < Lines ; i++)
{
Len = BufferLines[i][-1];
if(Len)
{
SetIoErr(0);
if(FWrite(SomeFile,BufferLines[i],Len,1) < 1)
{
Error = IoErr();
break;
}
}
SetIoErr(0);
if(FPrintf(SomeFile,"\n") < 1)
{
Error = IoErr();
break;
}
}
ReleaseSemaphore(BufferSemaphore);
Close(SomeFile);
AddProtection(DummyBuffer,FIBF_EXECUTE);
if(Config -> MiscConfig -> CreateIcons)
AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
BufferChanged = FALSE;
}
else
Error = IoErr();
if(Error)
ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
FreeAslRequest(FileRequest);
}
}
ReleaseWindows();
break;
/* Simply clear the screen and move the
* cursor to its home position.
*/
case MEN_CLEAR_SCREEN:
if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
XEmulatorClearConsole(XEM_IO);
else
{
DropMarker();
ConBypass("\033[2J\033[H",-1);
}
break;
/* Reset the current text rendering font. */
case MEN_RESET_FONT:
if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
XEmulatorResetCharset(XEM_IO);
else
{
DropMarker();
CurrentFont = TextFont;
SetFont(RPort,CurrentFont);
ConOutputUpdate();
}
break;
/* Reset the display styles and restore
* the colours.
*/
case MEN_RESET_STYLES:
if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
XEmulatorResetTextStyles(XEM_IO);
else
{
DropMarker();
ConBypass("\033[0m",-1);
ObtainSemaphore(&TerminalSemaphore);
ClearCursor();
CurrentCharWidth = SCALE_NORMAL;
if(!Config -> EmulationConfig -> LockColour)
{
ForegroundPen = GetPenIndex(SafeTextPen);
BackgroundPen = 0;
}
SetMask(RPort,DepthMask);
UpdatePens();
ConFontScaleUpdate();
DrawCursor();
ReleaseSemaphore(&TerminalSemaphore);
}
break;
/* Reset the whole terminal. */
case MEN_RESET_TERMINAL:
if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
XEmulatorResetConsole(XEM_IO);
else
{
FreeMarker();
ConBypass("\033c",-1);
}
break;
case MEN_SET_EMULATION:
BlockWindows();
if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
{
OptionTitle = LocaleString(MSG_TERMMAIN_EMULATION_PREFERENCES_TXT);
NewOptions = FALSE;
XEmulatorOptions(XEM_IO);
if(NewOptions)
{
SetEmulatorOptions(XEM_PREFS_SAVE);
NewOptions = FALSE;
}
OptionTitle = NULL;
}
else
{
if(EmulationPanel(Config,NULL))
{
ConfigSetup();
ConfigChanged = TRUE;
}
}
ReleaseWindows();
break;
/* Set the serial preferences. */
case MEN_SERIAL:
BlockWindows();
if(SerialPanel(Config,NULL))
{
ConfigSetup();
ConfigChanged = TRUE;
}
ReleaseWindows();
break;
/* Set the modem preferences. */
case MEN_MODEM:
BlockWindows();
if(ModemPanel(Config,NULL))
{
FlowInit(TRUE);
ConfigChanged = TRUE;
}
ReleaseWindows();
break;
/* Set the screen preferences. */
case MEN_SCREEN:
BlockWindows();
if(ScreenPanel(Config,NULL))
{
if(memcmp(PrivateConfig -> ScreenConfig -> Colours,Config -> ScreenConfig -> Colours,sizeof(UWORD) * 16))
{
switch(Config -> ScreenConfig -> ColourMode)
{
case COLOUR_EIGHT:
CopyMem(Config -> ScreenConfig -> Colours,ANSIColours,16 * sizeof(UWORD));
break;
case COLOUR_SIXTEEN:
CopyMem(Config -> ScreenConfig -> Colours,EGAColours,16 * sizeof(UWORD));
break;
case COLOUR_AMIGA:
CopyMem(Config -> ScreenConfig -> Colours,DefaultColours,16 * sizeof(UWORD));
break;
case COLOUR_MONO:
CopyMem(Config -> ScreenConfig -> Colours,AtomicColours,16 * sizeof(UWORD));
break;
}
}
ConfigSetup();
ConfigChanged = TRUE;
}
else
{
if(memcmp(PrivateConfig -> ScreenConfig -> Colours,Config -> ScreenConfig -> Colours,sizeof(UWORD) * 16))
{
switch(Config -> ScreenConfig -> ColourMode)
{
case COLOUR_EIGHT:
CopyMem(Config -> ScreenConfig -> Colours,ANSIColours,16 * sizeof(UWORD));
break;
case COLOUR_SIXTEEN:
CopyMem(Config -> ScreenConfig -> Colours,EGAColours,16 * sizeof(UWORD));
break;
case COLOUR_AMIGA:
CopyMem(Config -> ScreenConfig -> Colours,DefaultColours,16 * sizeof(UWORD));
break;
case COLOUR_MONO:
CopyMem(Config -> ScreenConfig -> Colours,AtomicColours,16 * sizeof(UWORD));
break;
}
ConfigChanged = TRUE;
}
}
ReleaseWindows();
break;
/* Set the terminal preferences. */
case MEN_TERMINAL:
BlockWindows();
if(TerminalPanel(Config,NULL))
{
Update_CR_LF_Translation();
ConfigSetup();
ConfigChanged = TRUE;
}
ReleaseWindows();
break;
/* Set the clipboard preferences. */
case MEN_CLIPBOARD:
BlockWindows();
if(ClipPanel(Config,NULL))
{
ConfigSetup();
ConfigChanged = TRUE;
}
ReleaseWindows();
break;
/* Set the capture preferences. */
case MEN_CAPTURE:
BlockWindows();
if(CapturePanel(Config,NULL))
{
ConOutputUpdate();
ConfigSetup();
ConfigChanged = TRUE;
}
ReleaseWindows();
break;
/* Set the command preferences. */
case MEN_COMMANDS:
BlockWindows();
if(CommandPanel(Config,NULL))
ConfigChanged = TRUE;
ReleaseWindows();
break;
/* Set the miscellaneous preferences. */
case MEN_MISC:
BlockWindows();
if(MiscPanel(Config,NULL))
{
ConfigSetup();
ConfigChanged = TRUE;
}
ReleaseWindows();
break;
/* Set the path settings. */
case MEN_PATH:
BlockWindows();
if(PathPanel(Config,NULL))
ConfigChanged = TRUE;
ReleaseWindows();
break;
/* Set the file transfer options. */
case MEN_TRANSFER:
BlockWindows();
XprIO -> xpr_filename = NULL;
/* Set up the library options. */
if(XProtocolBase)
{
XPRCommandSelected = FALSE;
#ifdef ASYNC_XPR_SREAD
ClearSerial();
#endif
NewOptions = FALSE;
TransferBits = XProtocolSetup(XprIO);
#ifdef ASYNC_XPR_SREAD
RestartSerial();
#endif
DeleteTransferPanel(TRUE);
/* Successful? */
/* if(!XPRCommandSelected)*/
{
if(!(TransferBits & XPRS_SUCCESS))
{
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
CloseLibrary(XProtocolBase);
XProtocolBase = NULL;
LastXprLibrary[0] = 0;
TransferBits = 0;
SetTransferMenu(TRUE);
}
else
SaveProtocolOpts();
}
}
ReleaseWindows();
break;
/* Set the file transfer procol settings. */
case MEN_TRANSFER_PROTOCOL:
BlockWindows();
if(LibPanel(Config,NULL))
{
ConfigSetup();
ConfigChanged = TRUE;
FlowInit(TRUE);
}
ReleaseWindows();
break;
/* Set the translation tables. */
case MEN_TRANSLATION:
BlockWindows();
TranslationChanged |= TranslationPanel(&SendTable,&ReceiveTable,LastTranslation,Window,&TranslationChanged);
/* Choose the right console write routine. */
ConOutputUpdate();
ReleaseWindows();
break;
/* Set the keyboard macros. */
case MEN_MACROS:
BlockWindows();
if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
{
XEmulatorMacroKeyFilter(XEM_IO,NULL);
MacroChanged |= MacroPanel(MacroKeys,LastMacros,TRUE,Window,&MacroChanged);
SetupXEM_MacroKeys(MacroKeys);
}
else
MacroChanged |= MacroPanel(MacroKeys,LastMacros,TRUE,Window,&MacroChanged);
ReleaseWindows();
break;
/* Set the cursor keys. */
case MEN_CURSORKEYS:
BlockWindows();
CursorKeysChanged |= CursorPanel(CursorKeys,LastCursorKeys,Window,&CursorKeysChanged);
ReleaseWindows();
break;
/* Set the fast macros. */
case MEN_FAST_MACROS:
BlockWindows();
// Looks weird, doesn't it? Actually, it's quite harmless. If FastMacroPanel()
// returns TRUE, FastMacrosChanged won't be modified. If FastMacrosChanged is
// modified, it will always be set to FALSE and FastMacroPanel() will also return
// FALSE.
FastMacrosChanged |= FastMacroPanel(&FastMacroList,LastFastMacros,Window,&FastMacrosChanged);
ReleaseWindows();
break;
/* Set the hotkey preferences. */
case MEN_HOTKEYS:
BlockWindows();
if(HotkeyPanel(&Hotkeys,&HotkeysChanged))
{
if(!SetupCx())
MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_SET_UP_HOTKEYS_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
}
ReleaseWindows();
break;
/* Set the speech preferences. */
case MEN_SPEECH:
BlockWindows();
SpeechPanel();
ReleaseWindows();
break;
/* Set the sound preferences. */
case MEN_SOUND:
BlockWindows();
if(SoundPanel(&SoundConfig))
SoundInit();
ReleaseWindows();
break;
/* Edit the phone number patterns and rates. */
/* Edit the trap settings? */
case MEN_RATES:
BlockWindows();
PatternPanel();
ReleaseWindows();
break;
/* Open the preferences settings. */
case MEN_OPEN_SETTINGS:
BlockWindows();
strcpy(DummyBuffer,LastConfig);
DummyChar = PathPart(DummyBuffer);
*DummyChar = 0;
if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_OPEN_PREFERENCES_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.prefs",FALSE,FALSE,FALSE,NULL,TRUE))
{
if(ReadConfig(DummyBuffer,PrivateConfig))
{
SwapConfig(PrivateConfig,Config);
strcpy(LastConfig,DummyBuffer);
ConfigSetup();
ConfigChanged = FALSE;
}
else
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
FreeAslRequest(FileRequest);
}
ReleaseWindows();
break;
/* Save the terminal preferences. */
case MEN_SAVE_SETTINGS:
if(LastConfig[0])
{
BlockWindows();
if(!Screen)
PutWindowInfo(WINDOW_MAIN,Window -> LeftEdge,Window -> TopEdge,Window -> Width,Window -> Height);
if(!WriteConfig(LastConfig,Config))
ShowError(Window,ERR_SAVE_ERROR,IoErr(),LastConfig);
else
ConfigChanged = FALSE;
ReleaseWindows();
break;
}
/* Save the terminal preferences to a
* given file name.
*/
case MEN_SAVE_SETTINGS_AS:
BlockWindows();
strcpy(DummyBuffer,LastConfig);
DummyChar = PathPart(DummyBuffer);
*DummyChar = 0;
if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_PREFERENCES_AS_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.prefs",TRUE,FALSE,FALSE,NULL,TRUE))
{
if(!Screen)
PutWindowInfo(WINDOW_MAIN,Window -> LeftEdge,Window -> TopEdge,Window -> Width,Window -> Height);
if(WriteConfig(DummyBuffer,Config))
{
strcpy(LastConfig,DummyBuffer);
ConfigChanged = FALSE;
}
else
ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
FreeAslRequest(FileRequest);
}
ReleaseWindows();
break;
/* Show terminal information window. */
case MEN_STATUS_WINDOW:
if(InfoWindow)
CloseInfoWindow();
else
OpenInfoWindow();
break;
case MEN_REVIEW_WINDOW:
if(ReviewWindow)
DeleteReview();
else
CreateReview();
break;
case MEN_MATRIX_WINDOW:
if(MatrixWindow)
CloseMatrixWindow();
else
OpenMatrixWindow(Window);
break;
/* Open the packet window if necessary, else
* just activate it.
*/
case MEN_PACKET_WINDOW:
CreatePacketWindow();
break;
// Enable or disable the packet window
case MEN_CHAT_LINE:
if(Item = FindThisItem(Menu,MEN_CHAT_LINE))
{
BOOL NewState;
if(Item -> Flags & CHECKED)
NewState = TRUE;
else
NewState = FALSE;
if(ChatMode != NewState)
{
ChatMode = NewState;
ResetDisplay = TRUE;
}
}
break;
/* Toggle the presence of the fast! macro panel. */
case MEN_FAST_MACROS_WINDOW:
if(FastWindow)
CloseFastWindow();
else
OpenFastWindow();
break;
/* Open the upload queue window. */
case MEN_UPLOAD_QUEUE_WINDOW:
CreateQueueProcess();
break;
default:if(Code >= DIAL_MENU_LIMIT)
{
LONG Index = Code - DIAL_MENU_LIMIT;
ObtainSemaphore(&OnlineSemaphore);
if(!LocalDialList && (!Online || Config -> MiscConfig -> ProtectiveMode))
{
ReleaseSemaphore(&OnlineSemaphore);
if(LocalDialList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY))
{
LONG i;
/* Clear previous list contents, we
* don't want to redial yet.
*/
for(i = 0 ; i < NumPhoneEntries ; i++)
Phonebook[i] -> Count = -1;
NewList(LocalDialList);
}
}
else
ReleaseSemaphore(&OnlineSemaphore);
if(Phonebook[Index] -> Count == -1)
{
if(LocalDialList)
{
struct PhoneNode *NewNode;
/* Create a new node to be added to the dial list. */
if(NewNode = (struct PhoneNode *)AllocVecPooled(sizeof(struct PhoneNode),MEMF_ANY | MEMF_CLEAR))
{
/* Take care of the name and the corresponding phone book entry. */
NewNode -> VanillaNode . ln_Name = NewNode -> LocalName;
NewNode -> Entry = Phonebook[Index];
Phonebook[Index] -> Count = ++LocalCount;
SPrintf(NewNode -> LocalName,"%3ld - %s",LocalCount + 1,Phonebook[Index] -> Header -> Name);
/* Install back-link. */
NewNode -> Entry -> Node = NewNode;
AddTail(LocalDialList,&NewNode -> VanillaNode);
}
}
}
}
break;
}
}
/* HandleMenu(ULONG Code,ULONG Qualifier):
*
* Skip along the number of selected menu items and
* handle the associated functions.
*/
VOID __regargs
HandleMenu(ULONG Code,ULONG Qualifier)
{
struct MenuItem *MenuItem;
DisplayReopened = FALSE;
/* Check until the last menuitem has been
* processed.
*/
while(Code != MENUNULL)
{
/* Pick up the associated menu item. */
if(MenuItem = ItemAddress(Menu,Code))
{
HandleMenuCode((ULONG)GTMENUITEM_USERDATA(MenuItem),Qualifier);
if(Apocalypse)
return;
if(DisplayReopened)
{
DisplayReopened = FALSE;
return;
}
Code = MenuItem -> NextSelect;
}
else
break;
}
/* If the modem is still online, provide help. */
if(LocalDialList)
{
if(!AskDial(Window))
{
FreeList(LocalDialList);
FreeVecPooled(LocalDialList);
LocalDialList = NULL;
LocalCount = -1;
}
}
HandleLocalDialList(FALSE);
}
/* HandleWorkbenchWindow():
*
* Handle input coming from the Workbench window.
*/
BYTE
HandleWorkbenchWindow()
{
struct FileInfoBlock *FileInfo;
struct AppMessage *AppMessage;
if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
{
struct FileTransferInfo *Info;
if(Info = AllocFileTransferInfo())
{
LONG FilesFound = 0,i;
BYTE Success = TRUE;
while(AppMessage = (struct AppMessage *)GetMsg(WorkbenchPort))
{
if(Success && AppMessage -> am_Type == MTYPE_APPWINDOW)
{
for(i = 0 ; Success && i < AppMessage -> am_NumArgs ; i++)
{
if(AppMessage -> am_ArgList[i] . wa_Lock && AppMessage -> am_ArgList[i] . wa_Name)
{
BPTR OldLock;
if(OldLock = CurrentDir(AppMessage -> am_ArgList[i] . wa_Lock))
{
BPTR FileLock;
if(FileLock = Lock(AppMessage -> am_ArgList[i] . wa_Name,ACCESS_READ))
{
if(Examine(FileLock,FileInfo))
{
if(FileInfo -> fib_DirEntryType < 0)
{
if(NameFromLock(FileLock,SharedBuffer,512))
{
if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
Success = FALSE;
else
{
FilesFound++;
if(Config -> TransferConfig -> TransferIcons)
{
BPTR InfoLock;
strcat(SharedBuffer,".info");
if(InfoLock = Lock(SharedBuffer,ACCESS_READ))
{
if(Examine(InfoLock,FileInfo))
{
if(FileInfo -> fib_DirEntryType < 0)
{
if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
Success = FALSE;
else
FilesFound++;
}
}
UnLock(InfoLock);
}
}
}
}
}
}
UnLock(FileLock);
}
CurrentDir(OldLock);
}
}
}
}
ReplyMsg((struct Message *)AppMessage);
}
if(FilesFound)
{
SortFileTransferInfo(Info);
BlockWindows();
switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILES_AS_TXT),LocaleString(MSG_TERMMAIN_BINARY_UPLOAD_CANCEL_TXT)))
{
case 1: BinaryTransfer = TRUE;
FileTransferInfo = Info;
StartXprSendFromList(TRANSFER_BINARY,TRUE);
break;
case 2: BinaryTransfer = FALSE;
FileTransferInfo = Info;
StartXprSendFromList(TRANSFER_TEXT,TRUE);
break;
case 0: FreeFileTransferInfo(Info);
break;
}
ReleaseWindows();
}
}
FreeDosObject(DOS_FIB,FileInfo);
}
while(AppMessage = (struct AppMessage *)GetMsg(WorkbenchPort))
ReplyMsg((struct Message *)AppMessage);
return(FALSE);
}
/* HandleIconify():
*
* Handle program iconification.
*/
VOID
HandleIconify()
{
BYTE Released = FALSE;
/* Set the wait mouse pointer... */
BlockWindows();
/* Open workbench.library. */
if(WorkbenchBase)
{
/* Open icon.library. */
if(IconBase)
{
struct DiskObject *Icon = NULL;
UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
strcpy(LocalBuffer,Config -> PathConfig -> DefaultStorage);
if(AddPart(LocalBuffer,"term_SleepIcon",MAX_FILENAME_LENGTH))
Icon = GetDiskObject(LocalBuffer);
if(!Icon)
Icon = GetDiskObject("PROGDIR:term_SleepIcon");
if(!Icon)
{
if(!(Icon = GetProgramIcon()))
Icon = GetDefDiskObject(WBTOOL);
}
/* Did we get an icon? */
if(Icon)
{
struct MsgPort *IconPort;
/* Reset the icon type. */
Icon -> do_Type = NULL;
/* Default icon position. */
Icon -> do_CurrentX = NO_ICON_POSITION;
Icon -> do_CurrentY = NO_ICON_POSITION;
/* Create the Workbench reply port. */
if(IconPort = CreateMsgPort())
{
struct AppIcon *AppIcon;
/* Add the application icon. */
if(AppIcon = AddAppIconA(0,0,TermIDString,IconPort,NULL,Icon,NULL))
{
struct AppMessage *AppMessage;
UBYTE *String,*Error;
ULONG SignalSet;
/* Reset the guardian. */
IconTerminated = FALSE;
/* Release the window. */
Released = TRUE;
ReleaseWindows();
WindowBox . Left = Window -> LeftEdge;
WindowBox . Top = Window -> TopEdge;
WindowBox . Width = Window -> Width;
WindowBox . Height = Window -> Height;
/* Close the display. full stop. */
if(DeleteDisplay())
{
/* Reset and release the serial driver. */
if(Config -> MiscConfig -> ReleaseDevice)
{
ClearSerial();
DeleteSerial();
}
/* Wait for double-click. */
IconLoop: while(!IconTerminated)
{
SignalSet = Wait(PORTMASK(IconPort) | SIG_REXX | SIGBREAKF_CTRL_F);
if(SignalSet & PORTMASK(IconPort))
{
/* Pick up application messages. */
while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
{
/* Received a double-click? */
IconTerminated = TRUE;
ReplyMsg(AppMessage);
}
}
/* Wake up if ARexx command received. */
if(SignalSet & SIG_REXX)
while(HandleRexx());
if(SignalSet & SIGBREAKF_CTRL_F)
IconTerminated = TRUE;
}
/* Open the serial driver. */
if(Config -> MiscConfig -> ReleaseDevice)
{
if(Error = CreateSerial())
{
DeleteSerial();
switch(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_IGNORE_QUIT_TXT),Error))
{
case 1: IconTerminated = FALSE;
goto IconLoop;
case 0: MainTerminated = TRUE;
}
}
else
{
if(SerialMessage)
{
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
SerialMessage = NULL;
}
}
}
if(CantQuit && MainTerminated)
MainTerminated = FALSE;
/* Create the display. */
if(!MainTerminated)
{
if(String = CreateDisplay(FALSE))
{
if(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_QUIT_TXT),String))
{
ClearSerial();
DeleteSerial();
IconTerminated = FALSE;
goto IconLoop;
}
else
MainTerminated = TRUE;
}
else
{
BumpWindow(Window);
PubScreenStuff();
}
}
}
else
{
BlockWindows();
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
ReleaseWindows();
}
/* Remove the application icon. */
RemoveAppIcon(AppIcon);
/* Reply pending messages. */
while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
ReplyMsg(AppMessage);
}
else
MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_ADD_APPLICATION_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
DeleteMsgPort(IconPort);
}
else
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_CREATE_MSGPORT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
FreeDiskObject(Icon);
}
else
MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_TOOL_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
}
else
MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_ICON_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
}
else
MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_WORKBENCH_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
if(!Released)
ReleaseWindows();
/* Finished! */
DoIconify = FALSE;
}
/* HandleOnlineCleanup():
*
* Perform offline cleanup tasks.
*/
VOID __regargs
HandleOnlineCleanup(BOOL Hangup)
{
SoundPlay(SOUND_DISCONNECT);
/* Execute logoff macro. */
if(Config -> CommandConfig -> LogoffMacro[0] && WasOnline)
SerialCommand(Config -> CommandConfig -> LogoffMacro);
StopCall(FALSE);
if(CurrentPay)
{
if(Hangup)
LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_COST_TXT),CreateSum(CurrentPay,TRUE));
else
LogAction(LocaleString(MSG_TERMAUX_CARRIER_LOST_COST_TXT),CreateSum(CurrentPay,TRUE));
}
else
{
if(Hangup)
LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_TXT));
else
LogAction(LocaleString(MSG_TERMAUX_CARRIER_LOST_TXT));
}
SetDialMenu(TRUE);
if(!Hangup)
Say(LocaleString(MSG_TERMAUX_CARRIER_LOST_TXT));
/* Clear the password. */
Password[0] = 0;
UserName[0] = 0;
CurrentBBSName[0] = 0;
CurrentBBSComment[0] = 0;
CurrentBBSNumber[0] = 0;
ObtainSemaphore(&OnlineSemaphore);
if(!Config -> SerialConfig -> CheckCarrier || Config -> SerialConfig -> DirectConnection)
Online = WasOnline = FALSE;
ReleaseSemaphore(&OnlineSemaphore);
ObtainSemaphore(&PatternSemaphore);
ChosenEntry = NULL;
ChosenPattern = NULL;
ReleaseSemaphore(&PatternSemaphore);
LimitCount = -1;
/* Previous configuration available? */
if(BackupConfig)
{
/* Remember old configuration. */
SaveConfig(Config,PrivateConfig);
/* Copy configuration. */
SaveConfig(BackupConfig,Config);
/* Set up new configuration. */
ConfigSetup();
/* Free old configuration. */
DeleteConfiguration(BackupConfig);
BackupConfig = NULL;
}
if(!ResetDisplay && CurrentPay)
{
/* Reset the text rendering styles, font, etc. in
* order to keep the following text from getting
* illegible.
*/
SoftReset();
/* Display how much we expect
* the user will have to pay for
* this call.
*/
ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
CurrentPay = 0;
}
if(Config -> ModemConfig -> RedialAfterHangup || KeepRedialing)
{
if(DialList)
{
if(DialList -> lh_Head -> ln_Succ)
{
ObtainSemaphore(&OnlineSemaphore);
Online = WasOnline = FALSE;
ReleaseSemaphore(&OnlineSemaphore);
DoDial = DIAL_REDIAL;
}
else
{
if(KeepRedialing)
{
KeepRedialing = FALSE;
if(PhonebookAutoExit)
MainTerminated = TRUE;
}
}
}
else
KeepRedialing = FALSE;
}
}
/* HandleFlowChange():
*
* Handle data flow scanner information.
*/
VOID
HandleFlowChange()
{
ObtainSemaphore(&OnlineSemaphore);
if(Online)
{
if(FlowInfo . NoCarrier)
{
if(Config -> SerialConfig -> CheckCarrier && !Config -> SerialConfig -> DirectConnection)
{
/* Is the carrier still present? */
if(!(GetSerialStatus() & CIAF_COMCD)) // = Carrier detected
FlowInfo . NoCarrier = FALSE;
}
if(FlowInfo . NoCarrier)
{
if(Online)
{
WasOnline = Online;
Online = FALSE;
}
}
}
ReleaseSemaphore(&OnlineSemaphore);
}
else
{
ReleaseSemaphore(&OnlineSemaphore);
if(FlowInfo . Voice)
{
UBYTE DateTimeBuffer[256];
FormatStamp(NULL,NULL,NULL,DateTimeBuffer,FALSE);
WakeUp(Window,SOUND_VOICE);
ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_VOIC_CALL_TXT),DateTimeBuffer);
Say(LocaleString(MSG_TERMMAIN_SAY_INCOMING_VOICE_CALL_TXT));
}
if(FlowInfo . Ring)
{
UBYTE DateTimeBuffer[256];
FormatStamp(NULL,NULL,NULL,DateTimeBuffer,FALSE);
WakeUp(Window,SOUND_RING);
ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_CALL_TXT),DateTimeBuffer);
Say(LocaleString(MSG_GLOBAL_INCOMING_CALL_TXT));
}
if(FlowInfo . Connect)
{
/* Are we to check the carrier signal? */
if(Config -> SerialConfig -> CheckCarrier && !Config -> SerialConfig -> DirectConnection)
{
/* No carrier signal present? */
if(GetSerialStatus() & CIAF_COMCD) // = Carrier lost
FlowInfo . Connect = FALSE;
}
if(FlowInfo . Connect)
{
WakeUp(Window,SOUND_CONNECT);
ObtainSemaphore(&OnlineSemaphore);
if(!Online)
{
WasOnline = Online;
Online = TRUE;
}
BaudPending = FALSE;
ReleaseSemaphore(&OnlineSemaphore);
SetDialMenu(FALSE);
}
}
}
/* Check if we are to prompt the user for
* file transfer.
*/
if(FlowInfo . Signature)
{
WORD Type = FlowInfo . Signature - SCAN_SIGDEFAULTUPLOAD + TRANSFERSIG_DEFAULTUPLOAD;
switch(Type)
{
case TRANSFERSIG_DEFAULTUPLOAD:
BlockWindows();
switch(UploadPanel(TRUE))
{
case UPLOAD_TEXT:
BinaryTransfer = FALSE;
if(!StartXprSend(TRANSFER_TEXT,TRUE))
SerWrite(ZModemCancel,20);
break;
case UPLOAD_BINARY:
BinaryTransfer = TRUE;
if(!StartXprSend(TRANSFER_BINARY,TRUE))
SerWrite(ZModemCancel,20);
break;
case UPLOAD_ABORT:
SerWrite(ZModemCancel,20);
break;
case UPLOAD_BINARY_FROM_LIST:
StartUpload(UPLOAD_BINARY);
break;
case UPLOAD_TEXT_FROM_LIST:
StartUpload(UPLOAD_TEXT);
break;
}
ReleaseWindows();
break;
case TRANSFERSIG_DEFAULTDOWNLOAD:
BlockWindows();
switch(UploadPanel(FALSE))
{
case UPLOAD_TEXT:
BinaryTransfer = FALSE;
StartXprReceive(TRANSFER_TEXT,NULL,TRUE);
BinaryTransfer = TRUE;
break;
case UPLOAD_BINARY:
BinaryTransfer = TRUE;
StartXprReceive(TRANSFER_BINARY,NULL,TRUE);
break;
}
ReleaseWindows();
break;
case TRANSFERSIG_ASCIIUPLOAD:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary,Config -> TransferConfig -> ASCIIUploadType))
{
BinaryTransfer = FALSE;
StartXprSend(TRANSFER_ASCII,TRUE);
BinaryTransfer = TRUE;
}
ResetProtocol();
ReleaseWindows();
break;
case TRANSFERSIG_ASCIIDOWNLOAD:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> ASCIIDownloadLibrary,Config -> TransferConfig -> ASCIIDownloadType))
{
BinaryTransfer = FALSE;
StartXprReceive(TRANSFER_ASCII,NULL,TRUE);
BinaryTransfer = TRUE;
}
ResetProtocol();
ReleaseWindows();
break;
case TRANSFERSIG_TEXTUPLOAD:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary,Config -> TransferConfig -> TextUploadType))
{
BinaryTransfer = FALSE;
StartXprSend(TRANSFER_TEXT,TRUE);
BinaryTransfer = TRUE;
}
ResetProtocol();
ReleaseWindows();
break;
case TRANSFERSIG_TEXTDOWNLOAD:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> TextDownloadLibrary,Config -> TransferConfig -> TextDownloadType))
{
BinaryTransfer = FALSE;
StartXprReceive(TRANSFER_TEXT,NULL,TRUE);
BinaryTransfer = TRUE;
}
ResetProtocol();
ReleaseWindows();
break;
case TRANSFERSIG_BINARYUPLOAD:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> BinaryUploadLibrary,Config -> TransferConfig -> BinaryUploadType))
{
BinaryTransfer = TRUE;
StartXprSend(TRANSFER_BINARY,TRUE);
}
ResetProtocol();
ReleaseWindows();
break;
case TRANSFERSIG_BINARYDOWNLOAD:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> BinaryDownloadLibrary,Config -> TransferConfig -> BinaryDownloadType))
{
BinaryTransfer = TRUE;
StartXprReceive(TRANSFER_BINARY,NULL,TRUE);
}
ResetProtocol();
ReleaseWindows();
break;
}
}
FlowInit(TRUE);
}
/* HandleSerialReset():
*
* Handle serial device reset.
*/
VOID
HandleSerialReset()
{
ClearSerial();
DeleteSerial();
BlockWindows();
ReopenSerial();
ReleaseWindows();
}
/* HandleSerialRelease():
*
* Release the serial device driver, then reopen it again.
*/
VOID
HandleSerialRelease()
{
APTR OldPtr = ThisProcess -> pr_WindowPtr;
BYTE Continue,SerialClosed;
ThisProcess -> pr_WindowPtr = (APTR)Window;
/* This might happen if an ARexx user
* released the serial device and
* failed to reopen it.
*/
if(ReadPort)
SerialClosed = FALSE;
else
SerialClosed = TRUE;
BlockWindows();
/* Prevent catastrophes! */
if(!Config -> MiscConfig -> ProtectiveMode)
Continue = TRUE;
else
{
ObtainSemaphore(&OnlineSemaphore);
if(Online && !SerialClosed)
{
ReleaseSemaphore(&OnlineSemaphore);
if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
Continue = FALSE;
else
Continue = TRUE;
}
else
{
ReleaseSemaphore(&OnlineSemaphore);
Continue = TRUE;
}
}
if(Continue)
{
if(SerialClosed)
ReopenSerial();
else
{
ClearSerial();
DeleteSerial();
switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNIT_RESET_AND_RELEASED_TXT),LocaleString(MSG_TERMMAIN_RETURN_QUIT_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber))
{
case 0: MainTerminated = TRUE;
break;
case 1: ReopenSerial();
break;
case 2: DoIconify = TRUE;
break;
}
}
}
ReleaseSerial = FALSE;
ThisProcess -> pr_WindowPtr = OldPtr;
ReleaseWindows();
}
/* HandleExternalEmulation():
*
* Handle external emulation event.
*/
VOID
HandleExternalEmulation()
{
if(!XEmulatorSignal(XEM_IO,XEM_Signal))
{
CloseEmulator();
ResetDisplay = TRUE;
}
}
/* HandleSerialCheck():
*
* Handle routine checkup actions.
*/
BYTE
HandleSerialCheck()
{
// Attempt to lock the serial device?
if(PollODU)
{
// We don't want to poll too often
if(PollODUCount++ == 4)
{
PollODUCount = 0;
// Still supporting the locking protocol?
if(Config -> SerialConfig -> UseOwnDevUnit)
{
// Allocate the signal
if((OwnDevBit = AllocSignal(-1)) != -1)
{
// Give it a try
if(!AttemptDevUnit(Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,TermIDString,OwnDevBit))
{
// Check
ReopenSerial();
PollODU = FALSE;
}
else
{
// No success
FreeSignal(OwnDevBit);
OwnDevBit = -1;
}
}
}
else
PollODU = FALSE;
}
}
/* Take a look at the carrier signal. */
if(Config -> SerialConfig -> CheckCarrier && WriteRequest && !Config -> SerialConfig -> DirectConnection)
{
register UWORD Status = GetSerialStatus();
ObtainSemaphore(&OnlineSemaphore);
/* Still online? */
if(Online)
{
ReleaseSemaphore(&OnlineSemaphore);
/* Carrier detect signal lost? */
if(Status & CIAF_COMCD) // = Carrier lost
{
ObtainSemaphore(&OnlineSemaphore);
if(Online)
{
WasOnline = Online;
Online = FALSE;
}
ReleaseSemaphore(&OnlineSemaphore);
}
}
else
{
ReleaseSemaphore(&OnlineSemaphore);
/* Is the carrier detect signal
* present?
*/
if(!(Status & CIAF_COMCD)) // = Carrier detected
{
ObtainSemaphore(&OnlineSemaphore);
if(!Online)
{
WasOnline = Online;
Online = TRUE;
}
ReleaseSemaphore(&OnlineSemaphore);
BaudCount = 0;
BaudBuffer[0] = 0;
BaudPending = FALSE;
CurrentPay = 0;
ObtainSemaphore(&PatternSemaphore);
ChosenEntry = NULL;
ChosenPattern = NULL;
ReleaseSemaphore(&PatternSemaphore);
Password[0] = 0;
UserName[0] = 0;
SendStartup = FALSE;
LimitCount = -1;
CurrentBBSName[0] = 0;
CurrentBBSComment[0] = 0;
CurrentBBSNumber[0] = 0;
SetDialMenu(FALSE);
}
}
}
/* Check online time limit. */
if(!LimitCount)
{
LimitCount = -1;
BlockWindows();
SendARexxCommand(LimitMacro,TRUE);
ReleaseWindows();
}
/* Flush capture file contents to disk,
* this routine is executed each minute
* in order to store the captured data.
*/
if(BufferFlushCount-- <= 0)
{
BufferFlushCount = 60;
/* Flush the capture file. */
if(FileCapture)
BufferFlush(FileCapture);
}
return(FALSE);
}
/* HandleQueueMsg():
*
* Process the special message queue.
*/
BYTE
HandleQueueMsg()
{
struct DataMsg *Item;
if(Item = GetMsgItem(SpecialQueue))
{
struct FileTransferInfo *Info;
BYTE OldEcho;
switch(Item -> Type)
{
// Output data.
case DATAMSGTYPE_WRITE:
SerWrite(Item -> Data,Item -> Size);
break;
// Execute a command.
case DATAMSGTYPE_SERIALCOMMAND:
SerialCommand(Item -> Data);
break;
// Execute a command, but don't echo it.
case DATAMSGTYPE_SERIALCOMMANDNOECHO:
OldEcho = Config -> SerialConfig -> Duplex;
Config -> SerialConfig -> Duplex = DUPLEX_FULL;
SerialCommand(Item -> Data);
Config -> SerialConfig -> Duplex = OldEcho;
break;
// Output contents of clipboard
case DATAMSGTYPE_WRITECLIP:
if(!ClipInput)
{
if(!OpenClip(Item -> Size))
ClipInput = ClipXerox = TRUE;
else
ClipInput = ClipXerox = FALSE;
}
/* Are we reading input from the clipboard? */
if(ClipInput)
{
UBYTE InputBuffer[257];
WORD Len;
if((Len = GetClip(InputBuffer,256,TRUE)) < 0)
{
CloseClip();
ClipInput = FALSE;
if(ClipXerox)
{
if(Config -> ClipConfig -> InsertSuffix[0])
SerialCommand(Config -> ClipConfig -> InsertSuffix);
ClipXerox = FALSE;
}
ClipPrefix = FALSE;
}
else
{
if(!ClipPrefix && ClipXerox)
{
if(Config -> ClipConfig -> InsertPrefix[0])
SerialCommand(Config -> ClipConfig -> InsertPrefix);
ClipPrefix = TRUE;
}
if(Len > 0)
SendInputTextBuffer(InputBuffer,Len,FALSE,Config -> ClipConfig -> ConvertLF);
}
}
break;
// Start an upload
case DATAMSGTYPE_UPLOAD:
if(((struct List *)Item -> Data) -> lh_Head -> ln_Succ)
{
if(Info = AllocFileTransferInfo())
{
struct FileInfoBlock *FileInfo;
LONG FilesFound = 0,Type = Item -> Size;
if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
{
BPTR FileLock;
struct List *List;
struct Node *Node,*Next;
APTR OldPtr = ThisProcess -> pr_WindowPtr;
ThisProcess -> pr_WindowPtr = (APTR)-1;
List = (struct List *)Item -> Data;
for(Node = List -> lh_Head ; Next = Node -> ln_Succ ; Node = Next)
{
if(FileLock = Lock(Node -> ln_Name,ACCESS_READ))
{
if(Examine(FileLock,FileInfo))
{
if(FileInfo -> fib_DirEntryType < 0)
{
if(AddFileTransferNode(Info,Node -> ln_Name,FileInfo -> fib_Size))
FilesFound++;
if(Config -> TransferConfig -> TransferIcons)
{
BPTR InfoLock;
strcpy(SharedBuffer,Node -> ln_Name);
strcat(SharedBuffer,".info");
if(InfoLock = Lock(SharedBuffer,ACCESS_READ))
{
if(Examine(InfoLock,FileInfo))
{
if(FileInfo -> fib_DirEntryType < 0)
{
if(AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
FilesFound++;
}
}
UnLock(InfoLock);
}
}
Remove(Node);
FreeVecPooled(Node);
}
}
UnLock(FileLock);
}
}
ThisProcess -> pr_WindowPtr = OldPtr;
FreeDosObject(DOS_FIB,FileInfo);
}
DeleteMsgItem(Item);
Item = NULL;
if(FilesFound)
{
BlockWindows();
SortFileTransferInfo(Info);
switch(Type)
{
case UPLOAD_BINARY:
BinaryTransfer = TRUE;
FileTransferInfo = Info;
StartXprSendFromList(TRANSFER_BINARY,TRUE);
break;
case UPLOAD_TEXT:
BinaryTransfer = FALSE;
FileTransferInfo = Info;
StartXprSendFromList(TRANSFER_TEXT,TRUE);
break;
}
ReleaseWindows();
}
else
FreeFileTransferInfo(Info);
}
}
else
{
UBYTE Type = Item -> Size;
DeleteMsgItem(Item);
Item = NULL;
if(Type == UPLOAD_BINARY)
{
BinaryTransfer = TRUE;
if(!StartXprSend(TRANSFER_BINARY,TRUE))
SerWrite(ZModemCancel,20);
}
else
{
BinaryTransfer = FALSE;
if(!StartXprSend(TRANSFER_TEXT,TRUE))
SerWrite(ZModemCancel,20);
}
}
break;
// ARexx script execution finished.
case DATAMSGTYPE_COMMANDDONE:
if(CantQuit > 0)
CantQuit--;
BumpWindow(Window);
ReleaseWindows();
ObtainSemaphore(&ARexxQueueSemaphore);
ARexxRunning = FALSE;
if(ARexxQueue . lh_Head -> ln_Succ)
{
struct Node *Node;
if(Node = RemHead(&ARexxQueue))
{
ReleaseSemaphore(&ARexxQueueSemaphore);
SendARexxCommand(Node -> ln_Name,FALSE);
FreeVecPooled(Node);
}
else
ReleaseSemaphore(&ARexxQueueSemaphore);
}
else
ReleaseSemaphore(&ARexxQueueSemaphore);
break;
// Call a menu item
case DATAMSGTYPE_MENU:
HandleMenuCode((ULONG)Item -> Size,(ULONG)Item -> Data);
break;
// Rendezvous with external process
case DATAMSGTYPE_RENDEZVOUS:
if(ReadRequest && WriteRequest)
{
// Abort serial I/O processing
ClearSerial();
BlockWindows();
// Return the message, caution, we're not ready yet
Forbid();
DeleteMsgItem(Item);
Item = NULL;
// Prepare to wait...
ClrSignal(SIG_HANDSHAKE);
Wait(SIG_HANDSHAKE);
// Pick up the queue
RestartSerial();
Permit();
ReleaseWindows();
}
break;
// Discard current buffer contents
case DATAMSGTYPE_CLEARBUFFER:
FreeBuffer();
break;
}
if(Item)
DeleteMsgItem(Item);
return(TRUE);
}
else
return(FALSE);
}
/* HandleOwnDevUnit():
*
* Deal with the OwnDevUnit signal notification.
*/
BYTE
HandleOwnDevUnit()
{
ObtainSemaphore(&OnlineSemaphore);
if(!Online || !ReadPort || (Online && Config -> SerialConfig -> ReleaseODUWhenOnline))
{
ReleaseSemaphore(&OnlineSemaphore);
if(Config -> SerialConfig -> SatisfyODURequests == ODU_RELEASE)
HandleSerialRelease();
if(Config -> SerialConfig -> SatisfyODURequests == ODU_WAIT)
{
APTR OldPtr = ThisProcess -> pr_WindowPtr;
BYTE Continue,SerialClosed;
ThisProcess -> pr_WindowPtr = (APTR)Window;
/* This might happen if an ARexx user
* released the serial device and
* failed to reopen it.
*/
if(ReadPort)
SerialClosed = FALSE;
else
SerialClosed = TRUE;
BlockWindows();
/* Prevent catastrophes! */
ObtainSemaphore(&OnlineSemaphore);
if(Online && !SerialClosed && !Config -> SerialConfig -> ReleaseODUWhenOnline)
{
ReleaseSemaphore(&OnlineSemaphore);
if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
Continue = FALSE;
else
Continue = TRUE;
}
else
{
ReleaseSemaphore(&OnlineSemaphore);
Continue = TRUE;
}
if(Continue)
{
if(!SerialClosed)
{
ClearSerial();
DeleteSerial();
}
}
ThisProcess -> pr_WindowPtr = OldPtr;
ReleaseWindows();
// Start polling for the device to become
// available again
PollODU = TRUE;
}
}
else
ReleaseSemaphore(&OnlineSemaphore);
return(FALSE);
}
/* FullHangup():
*
* In a nutshell, do the full work required to hang up the line.
*/
VOID __regargs
FullHangup(BOOL ForceIt)
{
BlockWindows();
if(DialMsg)
{
DialMsg -> rm_Result1 = RC_WARN;
DialMsg -> rm_Result2 = 0;
ReplyMsg(DialMsg);
DialMsg = NULL;
}
HangUp();
ReleaseWindows();
if(Config -> SerialConfig -> CheckCarrier && !ForceIt && !Config -> SerialConfig -> DirectConnection)
HungUp = TRUE;
else
{
ObtainSemaphore(&OnlineSemaphore);
if(Online)
{
/* Remember online state. */
WasOnline = Online;
/* We are no longer online. */
Online = FALSE;
}
ReleaseSemaphore(&OnlineSemaphore);
HandleOnlineCleanup(TRUE);
}
}